@rocicorp/zero 0.26.0-canary.0 → 0.26.0-canary.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.
- package/out/shared/src/custom-key-map.d.ts +4 -4
- package/out/shared/src/custom-key-map.d.ts.map +1 -1
- package/out/shared/src/custom-key-map.js.map +1 -1
- package/out/shared/src/iterables.d.ts +6 -8
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +13 -7
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/options.d.ts +1 -0
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +5 -1
- package/out/shared/src/options.js.map +1 -1
- package/out/zero/package.json.js +1 -1
- package/out/zero/src/zero-cache-dev.js +7 -3
- package/out/zero/src/zero-cache-dev.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +10 -1
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +27 -7
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/observability/events.d.ts.map +1 -1
- package/out/zero-cache/src/observability/events.js +15 -5
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +10 -2
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +22 -4
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +0 -4
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -10
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +8 -2
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -14
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/replica-schema.js +8 -1
- package/out/zero-cache/src/services/change-source/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +5 -3
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +16 -5
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +3 -1
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config.yml +1 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +4 -4
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +9 -24
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +1 -2
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +51 -12
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +4 -3
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +3 -2
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.js +36 -31
- package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +5 -6
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +5 -23
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +6 -4
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -8
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -11
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +0 -2
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +2 -10
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +40 -42
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +0 -1
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js +0 -2
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +2 -5
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +1 -4
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-client/src/client/context.js +1 -0
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +2 -4
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +1 -1
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +7 -0
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +9 -1
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +1 -0
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +41 -2
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +9 -0
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.js +1 -0
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +1 -0
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js +1 -1
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/mutate/mutator.js +4 -4
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/query/create-builder.js +3 -5
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/query-registry.js +4 -4
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/package.json +3 -3
- package/out/zero-cache/src/types/schema-versions.d.ts +0 -12
- package/out/zero-cache/src/types/schema-versions.d.ts.map +0 -1
- package/out/zero-cache/src/types/schema-versions.js +0 -28
- package/out/zero-cache/src/types/schema-versions.js.map +0 -1
|
@@ -17,10 +17,10 @@ export declare class CustomKeyMap<K, V> {
|
|
|
17
17
|
has(key: K): boolean;
|
|
18
18
|
set(key: K, value: V): this;
|
|
19
19
|
get size(): number;
|
|
20
|
-
entries():
|
|
21
|
-
keys():
|
|
22
|
-
values():
|
|
23
|
-
[Symbol.iterator]():
|
|
20
|
+
entries(): MapIterator<[K, V]>;
|
|
21
|
+
keys(): MapIterator<K>;
|
|
22
|
+
values(): MapIterator<V>;
|
|
23
|
+
[Symbol.iterator](): MapIterator<[K, V]>;
|
|
24
24
|
}
|
|
25
25
|
export {};
|
|
26
26
|
//# sourceMappingURL=custom-key-map.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-key-map.d.ts","sourceRoot":"","sources":["../../../../shared/src/custom-key-map.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhF;;;;;;GAMG;AACH,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC;;IAC5B,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB;gBAK7C,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,EAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;IAU7C,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIvB,OAAO,CACL,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAE/D,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAMP,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAI1B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAK3B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"custom-key-map.d.ts","sourceRoot":"","sources":["../../../../shared/src/custom-key-map.ts"],"names":[],"mappings":"AAAA,KAAK,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEhF;;;;;;GAMG;AACH,qBAAa,YAAY,CAAC,CAAC,EAAE,CAAC;;IAC5B,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,kBAAkB;gBAK7C,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,SAAS,EAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI;IAU7C,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIvB,OAAO,CACL,UAAU,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,EAE/D,OAAO,CAAC,EAAE,GAAG,GACZ,IAAI;IAMP,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAI1B,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO;IAIpB,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAK3B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAEA,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAM9B,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC;IAMtB,MAAM,IAAI,WAAW,CAAC,CAAC,CAAC;IAMzB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAGzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-key-map.js","sources":["../../../../shared/src/custom-key-map.ts"],"sourcesContent":["type Primitive = undefined | null | boolean | string | number | symbol | bigint;\n\n/**\n * A {@link Map} that uses a custom key transformation function to convert keys\n * to a primitive type that can be used as a {@link Map} key.\n *\n * This allows for using objects as keys in a {@link Map} without worrying about\n * reference equality.\n */\nexport class CustomKeyMap<K, V> {\n readonly [Symbol.toStringTag] = 'CustomKeyMap';\n readonly #toKey: (key: K) => Primitive;\n readonly #map = new Map<Primitive, readonly [K, V]>();\n\n constructor(\n toKey: (key: K) => Primitive,\n iterable?: Iterable<readonly [K, V]> | null,\n ) {\n this.#toKey = toKey;\n if (iterable) {\n for (const [key, value] of iterable ?? []) {\n this.#map.set(toKey(key), [key, value]);\n }\n }\n }\n\n clear(): void {\n this.#map.clear();\n }\n\n delete(key: K): boolean {\n return this.#map.delete(this.#toKey(key));\n }\n\n forEach(\n callbackfn: (value: V, key: K, map: CustomKeyMap<K, V>) => void,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n thisArg?: any,\n ): void {\n for (const [key, value] of this.#map.values()) {\n callbackfn.call(thisArg, value, key, this);\n }\n }\n\n get(key: K): V | undefined {\n return this.#map.get(this.#toKey(key))?.[1];\n }\n\n has(key: K): boolean {\n return this.#map.has(this.#toKey(key));\n }\n\n set(key: K, value: V): this {\n this.#map.set(this.#toKey(key), [key, value]);\n return this;\n }\n\n get size(): number {\n return this.#map.size;\n }\n\n *entries():
|
|
1
|
+
{"version":3,"file":"custom-key-map.js","sources":["../../../../shared/src/custom-key-map.ts"],"sourcesContent":["type Primitive = undefined | null | boolean | string | number | symbol | bigint;\n\n/**\n * A {@link Map} that uses a custom key transformation function to convert keys\n * to a primitive type that can be used as a {@link Map} key.\n *\n * This allows for using objects as keys in a {@link Map} without worrying about\n * reference equality.\n */\nexport class CustomKeyMap<K, V> {\n readonly [Symbol.toStringTag] = 'CustomKeyMap';\n readonly #toKey: (key: K) => Primitive;\n readonly #map = new Map<Primitive, readonly [K, V]>();\n\n constructor(\n toKey: (key: K) => Primitive,\n iterable?: Iterable<readonly [K, V]> | null,\n ) {\n this.#toKey = toKey;\n if (iterable) {\n for (const [key, value] of iterable ?? []) {\n this.#map.set(toKey(key), [key, value]);\n }\n }\n }\n\n clear(): void {\n this.#map.clear();\n }\n\n delete(key: K): boolean {\n return this.#map.delete(this.#toKey(key));\n }\n\n forEach(\n callbackfn: (value: V, key: K, map: CustomKeyMap<K, V>) => void,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n thisArg?: any,\n ): void {\n for (const [key, value] of this.#map.values()) {\n callbackfn.call(thisArg, value, key, this);\n }\n }\n\n get(key: K): V | undefined {\n return this.#map.get(this.#toKey(key))?.[1];\n }\n\n has(key: K): boolean {\n return this.#map.has(this.#toKey(key));\n }\n\n set(key: K, value: V): this {\n this.#map.set(this.#toKey(key), [key, value]);\n return this;\n }\n\n get size(): number {\n return this.#map.size;\n }\n\n *entries(): MapIterator<[K, V]> {\n for (const entry of this.#map.values()) {\n yield entry.slice(0, 2) as [K, V];\n }\n }\n\n *keys(): MapIterator<K> {\n for (const entry of this.#map.values()) {\n yield entry[0];\n }\n }\n\n *values(): MapIterator<V> {\n for (const entry of this.#map.values()) {\n yield entry[1];\n }\n }\n\n [Symbol.iterator](): MapIterator<[K, V]> {\n return this.entries();\n }\n}\n"],"names":[],"mappings":"AASO,MAAM,aAAmB;AAAA,EAC9B,CAAU,OAAO,WAAW,IAAI;AAAA,EACvB;AAAA,EACA,2BAAW,IAAA;AAAA,EAEpB,YACE,OACA,UACA;AACA,SAAK,SAAS;AACd,QAAI,UAAU;AACZ,iBAAW,CAAC,KAAK,KAAK,KAAK,YAAY,CAAA,GAAI;AACzC,aAAK,KAAK,IAAI,MAAM,GAAG,GAAG,CAAC,KAAK,KAAK,CAAC;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,KAAK,MAAA;AAAA,EACZ;AAAA,EAEA,OAAO,KAAiB;AACtB,WAAO,KAAK,KAAK,OAAO,KAAK,OAAO,GAAG,CAAC;AAAA,EAC1C;AAAA,EAEA,QACE,YAEA,SACM;AACN,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,UAAU;AAC7C,iBAAW,KAAK,SAAS,OAAO,KAAK,IAAI;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,IAAI,KAAuB;AACzB,WAAO,KAAK,KAAK,IAAI,KAAK,OAAO,GAAG,CAAC,IAAI,CAAC;AAAA,EAC5C;AAAA,EAEA,IAAI,KAAiB;AACnB,WAAO,KAAK,KAAK,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,EACvC;AAAA,EAEA,IAAI,KAAQ,OAAgB;AAC1B,SAAK,KAAK,IAAI,KAAK,OAAO,GAAG,GAAG,CAAC,KAAK,KAAK,CAAC;AAC5C,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,CAAC,UAA+B;AAC9B,eAAW,SAAS,KAAK,KAAK,OAAA,GAAU;AACtC,YAAM,MAAM,MAAM,GAAG,CAAC;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,CAAC,OAAuB;AACtB,eAAW,SAAS,KAAK,KAAK,OAAA,GAAU;AACtC,YAAM,MAAM,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EAEA,CAAC,SAAyB;AACxB,eAAW,SAAS,KAAK,KAAK,OAAA,GAAU;AACtC,YAAM,MAAM,CAAC;AAAA,IACf;AAAA,EACF;AAAA,EAEA,CAAC,OAAO,QAAQ,IAAyB;AACvC,WAAO,KAAK,QAAA;AAAA,EACd;AACF;"}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
export declare function joinIterables<T>(...iters: Iterable<T>[]): Generator<T, void, any>;
|
|
2
2
|
export declare function first<T>(stream: Iterable<T>): T | undefined;
|
|
3
3
|
export declare function once<T>(stream: Iterable<T>): Iterable<T>;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
[Symbol.iterator]():
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
export declare function wrapIterable<T>(iter: Iterable<T>): IterWrapper<T>;
|
|
4
|
+
type IteratorWithHelpers<T> = Iterator<T> & {
|
|
5
|
+
map<U>(f: (t: T, index: number) => U): IteratorWithHelpers<U>;
|
|
6
|
+
filter(p: (t: T, index: number) => boolean): IteratorWithHelpers<T>;
|
|
7
|
+
[Symbol.iterator](): IteratorWithHelpers<T>;
|
|
8
|
+
};
|
|
9
|
+
export declare function wrapIterable<T>(iter: Iterable<T>): IteratorWithHelpers<T>;
|
|
12
10
|
export {};
|
|
13
11
|
//# sourceMappingURL=iterables.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterables.d.ts","sourceRoot":"","sources":["../../../../shared/src/iterables.ts"],"names":[],"mappings":"AAAA,wBAAiB,aAAa,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,2BAIxD;AAwBD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAK3D;AAED,wBAAiB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAOzD;AAKD,
|
|
1
|
+
{"version":3,"file":"iterables.d.ts","sourceRoot":"","sources":["../../../../shared/src/iterables.ts"],"names":[],"mappings":"AAAA,wBAAiB,aAAa,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,2BAIxD;AAwBD,wBAAgB,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,SAAS,CAK3D;AAED,wBAAiB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAOzD;AAKD,KAAK,mBAAmB,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,GAAG;IAC1C,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,mBAAmB,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAC;AAyCF,wBAAgB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAEzE"}
|
|
@@ -25,23 +25,29 @@ function* once(stream) {
|
|
|
25
25
|
}
|
|
26
26
|
it.return?.();
|
|
27
27
|
}
|
|
28
|
+
const iteratorCtor = globalThis.Iterator;
|
|
29
|
+
const nativeIteratorFrom = iteratorCtor?.from;
|
|
30
|
+
const iteratorFrom = nativeIteratorFrom ?? ((e) => new IterWrapper(e));
|
|
28
31
|
class IterWrapper {
|
|
29
|
-
|
|
30
|
-
constructor(
|
|
31
|
-
this
|
|
32
|
+
#iterator;
|
|
33
|
+
constructor(iterable) {
|
|
34
|
+
this.#iterator = iterable[Symbol.iterator]();
|
|
35
|
+
}
|
|
36
|
+
next() {
|
|
37
|
+
return this.#iterator.next();
|
|
32
38
|
}
|
|
33
39
|
[Symbol.iterator]() {
|
|
34
|
-
return this
|
|
40
|
+
return this;
|
|
35
41
|
}
|
|
36
42
|
map(f) {
|
|
37
|
-
return new IterWrapper(mapIter(this
|
|
43
|
+
return new IterWrapper(mapIter(this, f));
|
|
38
44
|
}
|
|
39
45
|
filter(p) {
|
|
40
|
-
return new IterWrapper(filterIter(this
|
|
46
|
+
return new IterWrapper(filterIter(this, p));
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
function wrapIterable(iter) {
|
|
44
|
-
return
|
|
50
|
+
return iteratorFrom(iter);
|
|
45
51
|
}
|
|
46
52
|
export {
|
|
47
53
|
joinIterables,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iterables.js","sources":["../../../../shared/src/iterables.ts"],"sourcesContent":["export function* joinIterables<T>(...iters: Iterable<T>[]) {\n for (const iter of iters) {\n yield* iter;\n }\n}\n\nfunction* filterIter<T>(\n iter: Iterable<T>,\n p: (t: T, index: number) => boolean,\n): Iterable<T> {\n let index = 0;\n for (const t of iter) {\n if (p(t, index++)) {\n yield t;\n }\n }\n}\n\nfunction* mapIter<T, U>(\n iter: Iterable<T>,\n f: (t: T, index: number) => U,\n): Iterable<U> {\n let index = 0;\n for (const t of iter) {\n yield f(t, index++);\n }\n}\n\nexport function first<T>(stream: Iterable<T>): T | undefined {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n it.return?.();\n return value;\n}\n\nexport function* once<T>(stream: Iterable<T>): Iterable<T> {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n if (value !== undefined) {\n yield value;\n }\n it.return?.();\n}\n\n//
|
|
1
|
+
{"version":3,"file":"iterables.js","sources":["../../../../shared/src/iterables.ts"],"sourcesContent":["export function* joinIterables<T>(...iters: Iterable<T>[]) {\n for (const iter of iters) {\n yield* iter;\n }\n}\n\nfunction* filterIter<T>(\n iter: Iterable<T>,\n p: (t: T, index: number) => boolean,\n): Iterable<T> {\n let index = 0;\n for (const t of iter) {\n if (p(t, index++)) {\n yield t;\n }\n }\n}\n\nfunction* mapIter<T, U>(\n iter: Iterable<T>,\n f: (t: T, index: number) => U,\n): Iterable<U> {\n let index = 0;\n for (const t of iter) {\n yield f(t, index++);\n }\n}\n\nexport function first<T>(stream: Iterable<T>): T | undefined {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n it.return?.();\n return value;\n}\n\nexport function* once<T>(stream: Iterable<T>): Iterable<T> {\n const it = stream[Symbol.iterator]();\n const {value} = it.next();\n if (value !== undefined) {\n yield value;\n }\n it.return?.();\n}\n\n// ES2024 Iterator helpers are available in Node 22+ and part of ES2024.\n// https://github.com/tc39/proposal-iterator-helpers\n\ntype IteratorWithHelpers<T> = Iterator<T> & {\n map<U>(f: (t: T, index: number) => U): IteratorWithHelpers<U>;\n filter(p: (t: T, index: number) => boolean): IteratorWithHelpers<T>;\n [Symbol.iterator](): IteratorWithHelpers<T>;\n};\n\ntype IteratorConstructor = {\n from<T>(this: void, iter: Iterable<T>): IteratorWithHelpers<T>;\n};\n\n// Check if native Iterator.from is available and bind it once at startup\n// We use globalThis to access the runtime value safely\nconst iteratorCtor = (globalThis as {Iterator?: IteratorConstructor}).Iterator;\nconst nativeIteratorFrom = iteratorCtor?.from as\n | (<T>(iter: Iterable<T>) => IteratorWithHelpers<T>)\n | undefined;\n\nconst iteratorFrom: <T>(e: Iterable<T>) => IteratorWithHelpers<T> =\n nativeIteratorFrom ?? (e => new IterWrapper(e));\n\n// Fallback implementation for environments without ES2024 Iterator helpers\nclass IterWrapper<T> implements IteratorWithHelpers<T>, IterableIterator<T> {\n readonly #iterator: Iterator<T>;\n\n constructor(iterable: Iterable<T>) {\n this.#iterator = iterable[Symbol.iterator]();\n }\n\n next(): IteratorResult<T> {\n return this.#iterator.next();\n }\n\n [Symbol.iterator](): IteratorWithHelpers<T> {\n return this;\n }\n\n map<U>(f: (t: T, index: number) => U): IterWrapper<U> {\n return new IterWrapper(mapIter(this, f));\n }\n\n filter(p: (t: T, index: number) => boolean): IterWrapper<T> {\n return new IterWrapper(filterIter(this, p));\n }\n}\n\nexport function wrapIterable<T>(iter: Iterable<T>): IteratorWithHelpers<T> {\n return iteratorFrom(iter);\n}\n"],"names":[],"mappings":"AAAO,UAAU,iBAAoB,OAAsB;AACzD,aAAW,QAAQ,OAAO;AACxB,WAAO;AAAA,EACT;AACF;AAEA,UAAU,WACR,MACA,GACa;AACb,MAAI,QAAQ;AACZ,aAAW,KAAK,MAAM;AACpB,QAAI,EAAE,GAAG,OAAO,GAAG;AACjB,YAAM;AAAA,IACR;AAAA,EACF;AACF;AAEA,UAAU,QACR,MACA,GACa;AACb,MAAI,QAAQ;AACZ,aAAW,KAAK,MAAM;AACpB,UAAM,EAAE,GAAG,OAAO;AAAA,EACpB;AACF;AASO,UAAU,KAAQ,QAAkC;AACzD,QAAM,KAAK,OAAO,OAAO,QAAQ,EAAA;AACjC,QAAM,EAAC,MAAA,IAAS,GAAG,KAAA;AACnB,MAAI,UAAU,QAAW;AACvB,UAAM;AAAA,EACR;AACA,KAAG,SAAA;AACL;AAiBA,MAAM,eAAgB,WAAgD;AACtE,MAAM,qBAAqB,cAAc;AAIzC,MAAM,eACJ,uBAAuB,CAAA,MAAK,IAAI,YAAY,CAAC;AAG/C,MAAM,YAAsE;AAAA,EACjE;AAAA,EAET,YAAY,UAAuB;AACjC,SAAK,YAAY,SAAS,OAAO,QAAQ,EAAA;AAAA,EAC3C;AAAA,EAEA,OAA0B;AACxB,WAAO,KAAK,UAAU,KAAA;AAAA,EACxB;AAAA,EAEA,CAAC,OAAO,QAAQ,IAA4B;AAC1C,WAAO;AAAA,EACT;AAAA,EAEA,IAAO,GAA+C;AACpD,WAAO,IAAI,YAAY,QAAQ,MAAM,CAAC,CAAC;AAAA,EACzC;AAAA,EAEA,OAAO,GAAqD;AAC1D,WAAO,IAAI,YAAY,WAAW,MAAM,CAAC,CAAC;AAAA,EAC5C;AACF;AAEO,SAAS,aAAgB,MAA2C;AACzE,SAAO,aAAa,IAAI;AAC1B;"}
|
|
@@ -42,5 +42,6 @@ export declare function parseOptionsAdvanced<T extends Options>(appOptions: T, o
|
|
|
42
42
|
env: Record<string, string>;
|
|
43
43
|
unknown?: string[];
|
|
44
44
|
};
|
|
45
|
+
export declare function flagToEnv(prefix: string, flag: string): string;
|
|
45
46
|
export declare function parseBoolean(optionName: string, input: string): boolean;
|
|
46
47
|
//# sourceMappingURL=options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../shared/src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAUrD,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC,YAAY,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAC,CAAC;AAiFhE;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,SAAK;;cAgC1E;AAeD,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,WAAW,CAAC,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAElD,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAExB,0BAA0B;IAC1B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,sGAAsG;IACtG,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,4BAA4B;IAC5B,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,iCAAiC;IACjC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,KAAK,CAAC;CACjD,CAAC;AAEF,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,EAC5C,UAAU,EAAE,CAAC,EACb,IAAI,GAAE,YAAiB,GACtB,MAAM,CAAC,CAAC,CAAC,CAEX;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EACpD,UAAU,EAAE,CAAC,EACb,IAAI,GAAE,YAAiB,GACtB;IAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,CA0KtE;AA6FD,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAQ7D"}
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../shared/src/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,kBAAkB,CAAC;AAUrD,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EACL,MAAM,EACN,OAAO,EACP,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,CAAC,MAAM,aAAa,CAAC;AAEjC,YAAY,EAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,EAAC,CAAC;AAiFhE;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,SAAK;;cAgC1E;AAeD,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,WAAW,CAAC,EAAE;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAElD,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,0BAA0B;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAExB,0BAA0B;IAC1B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,sGAAsG;IACtG,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,4BAA4B;IAC5B,MAAM,CAAC,EAAE,cAAc,CAAC;IAExB,iCAAiC;IACjC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,KAAK,KAAK,CAAC;CACjD,CAAC;AAEF,wBAAgB,YAAY,CAAC,CAAC,SAAS,OAAO,EAC5C,UAAU,EAAE,CAAC,EACb,IAAI,GAAE,YAAiB,GACtB,MAAM,CAAC,CAAC,CAAC,CAEX;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,OAAO,EACpD,UAAU,EAAE,CAAC,EACb,IAAI,GAAE,YAAiB,GACtB;IAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CAAC,CA0KtE;AA6FD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAQ7D"}
|
|
@@ -2,7 +2,7 @@ import { template } from "chalk-template";
|
|
|
2
2
|
import commandLineArgs from "command-line-args";
|
|
3
3
|
import commandLineUsage from "command-line-usage";
|
|
4
4
|
import { createDefu } from "defu";
|
|
5
|
-
import {
|
|
5
|
+
import { toSnakeCase, toKebabCase } from "kasi";
|
|
6
6
|
import { stripVTControlCharacters } from "node:util";
|
|
7
7
|
import { assert } from "./asserts.js";
|
|
8
8
|
import { must } from "./must.js";
|
|
@@ -267,6 +267,9 @@ function parseArgs(optionDefs, argv, names) {
|
|
|
267
267
|
}
|
|
268
268
|
return [result, envObj, unknown];
|
|
269
269
|
}
|
|
270
|
+
function flagToEnv(prefix, flag) {
|
|
271
|
+
return toSnakeCase(prefix + flag).toUpperCase();
|
|
272
|
+
}
|
|
270
273
|
function parseBoolean(optionName, input) {
|
|
271
274
|
const bool = input.toLowerCase();
|
|
272
275
|
if (["true", "1"].includes(bool)) {
|
|
@@ -315,6 +318,7 @@ function showUsage(optionList, description = [], logger = console) {
|
|
|
315
318
|
logger.info?.(commandLineUsage(sections));
|
|
316
319
|
}
|
|
317
320
|
export {
|
|
321
|
+
flagToEnv,
|
|
318
322
|
parseBoolean,
|
|
319
323
|
parseOptions,
|
|
320
324
|
parseOptionsAdvanced
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sources":["../../../../shared/src/options.ts"],"sourcesContent":["import type {OptionalLogger} from '@rocicorp/logger';\nimport {template} from 'chalk-template';\nimport type {OptionDefinition} from 'command-line-args';\nimport commandLineArgs from 'command-line-args';\nimport commandLineUsage, {type Section} from 'command-line-usage';\nimport {createDefu} from 'defu';\nimport {toKebabCase, toSnakeCase} from 'kasi';\nimport {stripVTControlCharacters as stripAnsi} from 'node:util';\nimport {assert} from './asserts.ts';\nimport {must} from './must.ts';\nimport type {\n Config,\n Group,\n Option,\n Options,\n WrappedOptionType,\n} from './options-types.ts';\nimport * as v from './valita.ts';\n\nexport type {Config, Group, Option, Options, WrappedOptionType};\n\ntype Primitive = number | string | boolean;\ntype Value = Primitive | Array<Primitive>;\n\ntype RequiredOptionType =\n | v.Type<string>\n | v.Type<number>\n | v.Type<boolean>\n | v.Type<string[]>\n | v.Type<number[]>\n | v.Type<boolean[]>;\n\ntype OptionalOptionType =\n | v.Optional<string>\n | v.Optional<number>\n | v.Optional<boolean>\n | v.Optional<string[]>\n | v.Optional<number[]>\n | v.Optional<boolean[]>;\n\ntype OptionType = RequiredOptionType | OptionalOptionType;\n\n/**\n * Creates a defu instance that overrides arrays instead of merging them.\n */\nconst defu = createDefu((obj, key, value) => {\n if (!Array.isArray(value)) return;\n\n obj[key] = value;\n return true;\n});\n\n/**\n * Converts an Options instance into its corresponding {@link Config} schema.\n */\nfunction configSchema<T extends Options>(\n options: T,\n envNamePrefix: string,\n): v.Type<Config<T>> {\n function makeObjectType(options: Options | Group, group?: string) {\n return v.object(\n Object.fromEntries(\n Object.entries(options).map(\n ([name, value]): [string, OptionType | v.Type] => {\n const addErrorMessage = (t: OptionType) => {\n const {required} = getRequiredOrDefault(t);\n if (required) {\n // Adds an error message for required options that includes the\n // actual name of the option.\n const optionName = toSnakeCase(\n `${envNamePrefix}${group ? group + '_' : ''}${name}`,\n ).toUpperCase();\n return (t as v.Type<string>)\n .optional()\n .assert(\n val => val !== undefined,\n `Missing required option ${optionName}`,\n );\n }\n return t;\n };\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n return [name, addErrorMessage(value)];\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n return [name, addErrorMessage(type)];\n }\n // OptionGroup\n return [name, makeObjectType(value as Group, name)];\n },\n ),\n ),\n );\n }\n return makeObjectType(options) as v.Type<Config<T>>;\n}\n\n/**\n * Converts an Options instance into an \"env schema\", which is an object with\n * ENV names as its keys, mapped to optional or required string values\n * (corresponding to the optionality of the corresponding options).\n *\n * This is used as a format for encoding options for a multi-tenant version\n * of an app, with an envSchema for each tenant.\n */\nexport function envSchema<T extends Options>(options: T, envNamePrefix = '') {\n const fields: [string, v.Type<string> | v.Optional<string>][] = [];\n\n function addField(name: string, type: OptionType, group?: string) {\n const flag = group ? `${group}_${name}` : name;\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n\n const {required} = getRequiredOrDefault(type);\n fields.push([env, required ? v.string() : v.string().optional()]);\n }\n\n function addFields(o: Options | Group, group?: string) {\n Object.entries(o).forEach(([name, value]) => {\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n addField(name, value, group);\n return;\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n addField(name, type, group);\n return;\n }\n // OptionGroup\n addFields(value as Group, name);\n });\n }\n\n addFields(options);\n\n return v.object(Object.fromEntries(fields));\n}\n\n// type TerminalType is not exported from badrap/valita\ntype TerminalType = Parameters<\n Parameters<v.Type<unknown>['toTerminals']>[0]\n>[0];\n\nfunction getRequiredOrDefault(type: OptionType) {\n const defaultResult = v.testOptional<Value>(undefined, type);\n return {\n required: !defaultResult.ok,\n defaultValue: defaultResult.ok ? defaultResult.value : undefined,\n };\n}\n\nexport type ParseOptions = {\n /** Defaults to process.argv.slice(2) */\n argv?: string[];\n\n envNamePrefix?: string;\n\n description?: {header: string; content: string}[];\n\n /** Defaults to `false` */\n allowUnknown?: boolean;\n\n /** Defaults to `false` */\n allowPartial?: boolean;\n\n /** Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n\n /** Defaults to `true`. */\n emitDeprecationWarnings?: boolean;\n\n /** Defaults to `true`. When false, excludes default values from both config and env return values. */\n includeDefaults?: boolean;\n\n /** Defaults to `console` */\n logger?: OptionalLogger;\n\n /** Defaults to `process.exit` */\n exit?: (code?: number | string | null) => never;\n};\n\nexport function parseOptions<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): Config<T> {\n return parseOptionsAdvanced(appOptions, opts).config;\n}\n\nexport function parseOptionsAdvanced<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): {config: Config<T>; env: Record<string, string>; unknown?: string[]} {\n const {\n argv = process.argv.slice(2),\n envNamePrefix = '',\n description = [],\n allowUnknown = false,\n allowPartial = false,\n env: processEnv = process.env,\n emitDeprecationWarnings = true,\n includeDefaults = true,\n logger = console,\n exit = process.exit,\n } = opts;\n // The main logic for converting a valita Type spec to an Option (i.e. flag) spec.\n function addOption(field: string, option: WrappedOptionType, group?: string) {\n const {type, desc = [], deprecated, alias, hidden} = option;\n\n // The group name is prepended to the flag name.\n const flag = group ? toKebabCase(`${group}-${field}`) : toKebabCase(field);\n\n const {required, defaultValue} = getRequiredOrDefault(type);\n let multiple = type.name === 'array';\n const literals = new Set<string>();\n const terminalTypes = new Set<string>();\n\n type.toTerminals(getTerminalTypes);\n\n function getTerminalTypes(t: TerminalType) {\n switch (t.name) {\n case 'undefined':\n case 'optional':\n break;\n case 'array': {\n multiple = true;\n t.prefix.forEach(t => t.toTerminals(getTerminalTypes));\n t.rest?.toTerminals(getTerminalTypes);\n t.suffix.forEach(t => t.toTerminals(getTerminalTypes));\n break;\n }\n case 'literal':\n literals.add(String(t.value));\n terminalTypes.add(typeof t.value);\n break;\n default:\n terminalTypes.add(t.name);\n break;\n }\n }\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n if (terminalTypes.size > 1) {\n throw new TypeError(`${env} has mixed types ${[...terminalTypes]}`);\n }\n assert(terminalTypes.size === 1);\n const terminalType = [...terminalTypes][0];\n\n if (processEnv[env]) {\n if (multiple) {\n // Technically not water-tight; assumes values for the string[] flag don't contain commas.\n envArgv.push(`--${flag}`, ...processEnv[env].split(','));\n } else {\n envArgv.push(`--${flag}`, processEnv[env]);\n }\n }\n names.set(flag, {field, env});\n\n const spec = [\n (required\n ? '{italic required}'\n : defaultValue !== undefined\n ? `default: ${JSON.stringify(defaultValue)}`\n : 'optional') + '\\n',\n ];\n if (desc) {\n spec.push(...desc);\n }\n\n const typeLabel = [\n literals.size\n ? String([...literals].map(l => `{underline ${l}}`))\n : multiple\n ? `{underline ${terminalType}[]}`\n : `{underline ${terminalType}}`,\n ` ${env} env`,\n ];\n\n const opt = {\n name: flag,\n alias,\n type: valueParser(\n env,\n terminalType,\n logger,\n emitDeprecationWarnings ? deprecated : undefined,\n ),\n multiple,\n group,\n description: spec.join('\\n') + '\\n',\n typeLabel: typeLabel.join('\\n') + '\\n',\n hidden: hidden === undefined ? deprecated !== undefined : hidden,\n };\n optsWithoutDefaults.push(opt);\n optsWithDefaults.push({...opt, defaultValue});\n }\n\n const names = new Map<string, {field: string; env: string}>();\n const optsWithDefaults: DescribedOptionDefinition[] = [];\n const optsWithoutDefaults: DescribedOptionDefinition[] = [];\n const envArgv: string[] = [];\n\n try {\n for (const [name, val] of Object.entries(appOptions)) {\n const {type} = val as {type: unknown};\n if (v.instanceOfAbstractType(val)) {\n addOption(name, {type: val});\n } else if (v.instanceOfAbstractType(type)) {\n addOption(name, val as WrappedOptionType);\n } else {\n const group = name;\n for (const [name, option] of Object.entries(val as Group)) {\n const wrapped = v.instanceOfAbstractType(option)\n ? {type: option}\n : option;\n addOption(name, wrapped, group);\n }\n }\n }\n\n const [defaults, env1, unknown] = parseArgs(optsWithDefaults, argv, names);\n const [fromEnv, env2] = parseArgs(optsWithoutDefaults, envArgv, names);\n const [withoutDefaults, env3] = parseArgs(optsWithoutDefaults, argv, names);\n\n switch (unknown?.[0]) {\n case undefined:\n break;\n case '--help':\n case '-h':\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n break;\n default:\n if (!allowUnknown) {\n logger.error?.('Invalid arguments:', unknown);\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n }\n break;\n }\n\n const parsedArgs = includeDefaults\n ? defu(withoutDefaults, fromEnv, defaults)\n : defu(withoutDefaults, fromEnv);\n const env = includeDefaults\n ? {...env1, ...env2, ...env3}\n : {...env2, ...env3};\n\n let schema = configSchema(appOptions, envNamePrefix);\n if (allowPartial || !includeDefaults) {\n // TODO: Type configSchema() to return a v.ObjectType<...>\n schema = v.deepPartial(schema as v.ObjectType) as v.Type<Config<T>>;\n }\n return {\n config: v.parse(parsedArgs, schema),\n env,\n ...(unknown ? {unknown} : {}),\n };\n } catch (e) {\n logger.error?.(String(e));\n showUsage(optsWithDefaults, description, logger);\n throw e;\n }\n}\n\nfunction valueParser(\n optionName: string,\n typeName: string,\n logger: OptionalLogger,\n deprecated: string[] | undefined,\n) {\n return (input: string) => {\n if (deprecated) {\n logger.warn?.(\n template(\n `\\n${optionName} is deprecated:\\n` + deprecated.join('\\n') + '\\n',\n ),\n );\n }\n switch (typeName) {\n case 'string':\n return input;\n case 'boolean':\n return parseBoolean(optionName, input);\n case 'number': {\n const val = Number(input);\n if (Number.isNaN(val)) {\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n }\n return val;\n }\n default:\n // Should be impossible given the constraints of `Option`\n throw new TypeError(\n `${optionName} option has unsupported type ${typeName}`,\n );\n }\n };\n}\n\nfunction parseArgs(\n optionDefs: DescribedOptionDefinition[],\n argv: string[],\n names: Map<string, {field: string; env: string}>,\n) {\n function normalizeFlagValue(value: unknown) {\n // A --flag without value is parsed by commandLineArgs() to `null`,\n // but this is a common convention to set a boolean flag to true.\n return value === null ? true : value;\n }\n\n const {\n _all,\n _none: ungrouped,\n _unknown: unknown,\n ...config\n } = commandLineArgs(optionDefs, {\n argv,\n partial: true,\n });\n\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {};\n const envObj: Record<string, string> = {};\n\n function addFlag(flagName: string, value: unknown, group?: string) {\n const {field, env} = must(names.get(flagName));\n const normalized = normalizeFlagValue(value);\n if (group) {\n result[group][field] = normalized;\n } else {\n result[field] = normalized;\n }\n envObj[env] = String(normalized);\n }\n\n for (const [flagName, value] of Object.entries(ungrouped ?? {})) {\n addFlag(flagName, value);\n }\n\n // Then handle (potentially) grouped flags\n for (const [name, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n addFlag(name, value); // Flag, not a group\n } else {\n const group = name;\n result[group] = {};\n for (const [flagName, flagValue] of Object.entries(value)) {\n addFlag(flagName, flagValue, group);\n }\n }\n }\n\n return [result, envObj, unknown] as const;\n}\n\nexport function parseBoolean(optionName: string, input: string) {\n const bool = input.toLowerCase();\n if (['true', '1'].includes(bool)) {\n return true;\n } else if (['false', '0'].includes(bool)) {\n return false;\n }\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n}\n\nfunction showUsage(\n optionList: DescribedOptionDefinition[],\n description: {header: string; content: string}[] = [],\n logger: OptionalLogger = console,\n) {\n const hide: string[] = [];\n let leftWidth = 35;\n let rightWidth = 70;\n optionList.forEach(({name, typeLabel, description, hidden}) => {\n if (hidden) {\n hide.push(name);\n }\n const text = template(`${name} ${typeLabel ?? ''}`);\n const lines = stripAnsi(text).split('\\n');\n for (const l of lines) {\n leftWidth = Math.max(leftWidth, l.length + 2);\n }\n const desc = stripAnsi(template(description ?? '')).split('\\n');\n for (const l of desc) {\n rightWidth = Math.max(rightWidth, l.length + 2);\n }\n });\n\n const sections: Section[] = [\n {\n optionList,\n reverseNameOrder: true, // Display --flag-name before -alias\n hide,\n tableOptions: {\n columns: [\n {name: 'option', width: leftWidth},\n {name: 'description', width: rightWidth},\n ],\n noTrim: true,\n },\n },\n ];\n\n if (description) {\n sections.unshift(...description);\n }\n\n logger.info?.(commandLineUsage(sections));\n}\n\ntype DescribedOptionDefinition = OptionDefinition & {\n // Additional fields recognized by command-line-usage\n description?: string;\n typeLabel?: string | undefined;\n hidden?: boolean | undefined;\n};\n"],"names":["options","v.object","v.instanceOfAbstractType","v.testOptional","t","name","v.deepPartial","v.parse","description","stripAnsi"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"options.js","sources":["../../../../shared/src/options.ts"],"sourcesContent":["import type {OptionalLogger} from '@rocicorp/logger';\nimport {template} from 'chalk-template';\nimport type {OptionDefinition} from 'command-line-args';\nimport commandLineArgs from 'command-line-args';\nimport commandLineUsage, {type Section} from 'command-line-usage';\nimport {createDefu} from 'defu';\nimport {toKebabCase, toSnakeCase} from 'kasi';\nimport {stripVTControlCharacters as stripAnsi} from 'node:util';\nimport {assert} from './asserts.ts';\nimport {must} from './must.ts';\nimport type {\n Config,\n Group,\n Option,\n Options,\n WrappedOptionType,\n} from './options-types.ts';\nimport * as v from './valita.ts';\n\nexport type {Config, Group, Option, Options, WrappedOptionType};\n\ntype Primitive = number | string | boolean;\ntype Value = Primitive | Array<Primitive>;\n\ntype RequiredOptionType =\n | v.Type<string>\n | v.Type<number>\n | v.Type<boolean>\n | v.Type<string[]>\n | v.Type<number[]>\n | v.Type<boolean[]>;\n\ntype OptionalOptionType =\n | v.Optional<string>\n | v.Optional<number>\n | v.Optional<boolean>\n | v.Optional<string[]>\n | v.Optional<number[]>\n | v.Optional<boolean[]>;\n\ntype OptionType = RequiredOptionType | OptionalOptionType;\n\n/**\n * Creates a defu instance that overrides arrays instead of merging them.\n */\nconst defu = createDefu((obj, key, value) => {\n if (!Array.isArray(value)) return;\n\n obj[key] = value;\n return true;\n});\n\n/**\n * Converts an Options instance into its corresponding {@link Config} schema.\n */\nfunction configSchema<T extends Options>(\n options: T,\n envNamePrefix: string,\n): v.Type<Config<T>> {\n function makeObjectType(options: Options | Group, group?: string) {\n return v.object(\n Object.fromEntries(\n Object.entries(options).map(\n ([name, value]): [string, OptionType | v.Type] => {\n const addErrorMessage = (t: OptionType) => {\n const {required} = getRequiredOrDefault(t);\n if (required) {\n // Adds an error message for required options that includes the\n // actual name of the option.\n const optionName = toSnakeCase(\n `${envNamePrefix}${group ? group + '_' : ''}${name}`,\n ).toUpperCase();\n return (t as v.Type<string>)\n .optional()\n .assert(\n val => val !== undefined,\n `Missing required option ${optionName}`,\n );\n }\n return t;\n };\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n return [name, addErrorMessage(value)];\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n return [name, addErrorMessage(type)];\n }\n // OptionGroup\n return [name, makeObjectType(value as Group, name)];\n },\n ),\n ),\n );\n }\n return makeObjectType(options) as v.Type<Config<T>>;\n}\n\n/**\n * Converts an Options instance into an \"env schema\", which is an object with\n * ENV names as its keys, mapped to optional or required string values\n * (corresponding to the optionality of the corresponding options).\n *\n * This is used as a format for encoding options for a multi-tenant version\n * of an app, with an envSchema for each tenant.\n */\nexport function envSchema<T extends Options>(options: T, envNamePrefix = '') {\n const fields: [string, v.Type<string> | v.Optional<string>][] = [];\n\n function addField(name: string, type: OptionType, group?: string) {\n const flag = group ? `${group}_${name}` : name;\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n\n const {required} = getRequiredOrDefault(type);\n fields.push([env, required ? v.string() : v.string().optional()]);\n }\n\n function addFields(o: Options | Group, group?: string) {\n Object.entries(o).forEach(([name, value]) => {\n // OptionType\n if (v.instanceOfAbstractType(value)) {\n addField(name, value, group);\n return;\n }\n // WrappedOptionType\n const {type} = value;\n if (v.instanceOfAbstractType(type)) {\n addField(name, type, group);\n return;\n }\n // OptionGroup\n addFields(value as Group, name);\n });\n }\n\n addFields(options);\n\n return v.object(Object.fromEntries(fields));\n}\n\n// type TerminalType is not exported from badrap/valita\ntype TerminalType = Parameters<\n Parameters<v.Type<unknown>['toTerminals']>[0]\n>[0];\n\nfunction getRequiredOrDefault(type: OptionType) {\n const defaultResult = v.testOptional<Value>(undefined, type);\n return {\n required: !defaultResult.ok,\n defaultValue: defaultResult.ok ? defaultResult.value : undefined,\n };\n}\n\nexport type ParseOptions = {\n /** Defaults to process.argv.slice(2) */\n argv?: string[];\n\n envNamePrefix?: string;\n\n description?: {header: string; content: string}[];\n\n /** Defaults to `false` */\n allowUnknown?: boolean;\n\n /** Defaults to `false` */\n allowPartial?: boolean;\n\n /** Defaults to `process.env`. */\n env?: NodeJS.ProcessEnv;\n\n /** Defaults to `true`. */\n emitDeprecationWarnings?: boolean;\n\n /** Defaults to `true`. When false, excludes default values from both config and env return values. */\n includeDefaults?: boolean;\n\n /** Defaults to `console` */\n logger?: OptionalLogger;\n\n /** Defaults to `process.exit` */\n exit?: (code?: number | string | null) => never;\n};\n\nexport function parseOptions<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): Config<T> {\n return parseOptionsAdvanced(appOptions, opts).config;\n}\n\nexport function parseOptionsAdvanced<T extends Options>(\n appOptions: T,\n opts: ParseOptions = {},\n): {config: Config<T>; env: Record<string, string>; unknown?: string[]} {\n const {\n argv = process.argv.slice(2),\n envNamePrefix = '',\n description = [],\n allowUnknown = false,\n allowPartial = false,\n env: processEnv = process.env,\n emitDeprecationWarnings = true,\n includeDefaults = true,\n logger = console,\n exit = process.exit,\n } = opts;\n // The main logic for converting a valita Type spec to an Option (i.e. flag) spec.\n function addOption(field: string, option: WrappedOptionType, group?: string) {\n const {type, desc = [], deprecated, alias, hidden} = option;\n\n // The group name is prepended to the flag name.\n const flag = group ? toKebabCase(`${group}-${field}`) : toKebabCase(field);\n\n const {required, defaultValue} = getRequiredOrDefault(type);\n let multiple = type.name === 'array';\n const literals = new Set<string>();\n const terminalTypes = new Set<string>();\n\n type.toTerminals(getTerminalTypes);\n\n function getTerminalTypes(t: TerminalType) {\n switch (t.name) {\n case 'undefined':\n case 'optional':\n break;\n case 'array': {\n multiple = true;\n t.prefix.forEach(t => t.toTerminals(getTerminalTypes));\n t.rest?.toTerminals(getTerminalTypes);\n t.suffix.forEach(t => t.toTerminals(getTerminalTypes));\n break;\n }\n case 'literal':\n literals.add(String(t.value));\n terminalTypes.add(typeof t.value);\n break;\n default:\n terminalTypes.add(t.name);\n break;\n }\n }\n const env = toSnakeCase(`${envNamePrefix}${flag}`).toUpperCase();\n if (terminalTypes.size > 1) {\n throw new TypeError(`${env} has mixed types ${[...terminalTypes]}`);\n }\n assert(terminalTypes.size === 1);\n const terminalType = [...terminalTypes][0];\n\n if (processEnv[env]) {\n if (multiple) {\n // Technically not water-tight; assumes values for the string[] flag don't contain commas.\n envArgv.push(`--${flag}`, ...processEnv[env].split(','));\n } else {\n envArgv.push(`--${flag}`, processEnv[env]);\n }\n }\n names.set(flag, {field, env});\n\n const spec = [\n (required\n ? '{italic required}'\n : defaultValue !== undefined\n ? `default: ${JSON.stringify(defaultValue)}`\n : 'optional') + '\\n',\n ];\n if (desc) {\n spec.push(...desc);\n }\n\n const typeLabel = [\n literals.size\n ? String([...literals].map(l => `{underline ${l}}`))\n : multiple\n ? `{underline ${terminalType}[]}`\n : `{underline ${terminalType}}`,\n ` ${env} env`,\n ];\n\n const opt = {\n name: flag,\n alias,\n type: valueParser(\n env,\n terminalType,\n logger,\n emitDeprecationWarnings ? deprecated : undefined,\n ),\n multiple,\n group,\n description: spec.join('\\n') + '\\n',\n typeLabel: typeLabel.join('\\n') + '\\n',\n hidden: hidden === undefined ? deprecated !== undefined : hidden,\n };\n optsWithoutDefaults.push(opt);\n optsWithDefaults.push({...opt, defaultValue});\n }\n\n const names = new Map<string, {field: string; env: string}>();\n const optsWithDefaults: DescribedOptionDefinition[] = [];\n const optsWithoutDefaults: DescribedOptionDefinition[] = [];\n const envArgv: string[] = [];\n\n try {\n for (const [name, val] of Object.entries(appOptions)) {\n const {type} = val as {type: unknown};\n if (v.instanceOfAbstractType(val)) {\n addOption(name, {type: val});\n } else if (v.instanceOfAbstractType(type)) {\n addOption(name, val as WrappedOptionType);\n } else {\n const group = name;\n for (const [name, option] of Object.entries(val as Group)) {\n const wrapped = v.instanceOfAbstractType(option)\n ? {type: option}\n : option;\n addOption(name, wrapped, group);\n }\n }\n }\n\n const [defaults, env1, unknown] = parseArgs(optsWithDefaults, argv, names);\n const [fromEnv, env2] = parseArgs(optsWithoutDefaults, envArgv, names);\n const [withoutDefaults, env3] = parseArgs(optsWithoutDefaults, argv, names);\n\n switch (unknown?.[0]) {\n case undefined:\n break;\n case '--help':\n case '-h':\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n break;\n default:\n if (!allowUnknown) {\n logger.error?.('Invalid arguments:', unknown);\n showUsage(optsWithDefaults, description, logger);\n exit(0);\n }\n break;\n }\n\n const parsedArgs = includeDefaults\n ? defu(withoutDefaults, fromEnv, defaults)\n : defu(withoutDefaults, fromEnv);\n const env = includeDefaults\n ? {...env1, ...env2, ...env3}\n : {...env2, ...env3};\n\n let schema = configSchema(appOptions, envNamePrefix);\n if (allowPartial || !includeDefaults) {\n // TODO: Type configSchema() to return a v.ObjectType<...>\n schema = v.deepPartial(schema as v.ObjectType) as v.Type<Config<T>>;\n }\n return {\n config: v.parse(parsedArgs, schema),\n env,\n ...(unknown ? {unknown} : {}),\n };\n } catch (e) {\n logger.error?.(String(e));\n showUsage(optsWithDefaults, description, logger);\n throw e;\n }\n}\n\nfunction valueParser(\n optionName: string,\n typeName: string,\n logger: OptionalLogger,\n deprecated: string[] | undefined,\n) {\n return (input: string) => {\n if (deprecated) {\n logger.warn?.(\n template(\n `\\n${optionName} is deprecated:\\n` + deprecated.join('\\n') + '\\n',\n ),\n );\n }\n switch (typeName) {\n case 'string':\n return input;\n case 'boolean':\n return parseBoolean(optionName, input);\n case 'number': {\n const val = Number(input);\n if (Number.isNaN(val)) {\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n }\n return val;\n }\n default:\n // Should be impossible given the constraints of `Option`\n throw new TypeError(\n `${optionName} option has unsupported type ${typeName}`,\n );\n }\n };\n}\n\nfunction parseArgs(\n optionDefs: DescribedOptionDefinition[],\n argv: string[],\n names: Map<string, {field: string; env: string}>,\n) {\n function normalizeFlagValue(value: unknown) {\n // A --flag without value is parsed by commandLineArgs() to `null`,\n // but this is a common convention to set a boolean flag to true.\n return value === null ? true : value;\n }\n\n const {\n _all,\n _none: ungrouped,\n _unknown: unknown,\n ...config\n } = commandLineArgs(optionDefs, {\n argv,\n partial: true,\n });\n\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n const result: Record<string, any> = {};\n const envObj: Record<string, string> = {};\n\n function addFlag(flagName: string, value: unknown, group?: string) {\n const {field, env} = must(names.get(flagName));\n const normalized = normalizeFlagValue(value);\n if (group) {\n result[group][field] = normalized;\n } else {\n result[field] = normalized;\n }\n envObj[env] = String(normalized);\n }\n\n for (const [flagName, value] of Object.entries(ungrouped ?? {})) {\n addFlag(flagName, value);\n }\n\n // Then handle (potentially) grouped flags\n for (const [name, value] of Object.entries(config)) {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n addFlag(name, value); // Flag, not a group\n } else {\n const group = name;\n result[group] = {};\n for (const [flagName, flagValue] of Object.entries(value)) {\n addFlag(flagName, flagValue, group);\n }\n }\n }\n\n return [result, envObj, unknown] as const;\n}\n\nexport function flagToEnv(prefix: string, flag: string): string {\n return toSnakeCase(prefix + flag).toUpperCase();\n}\n\nexport function parseBoolean(optionName: string, input: string) {\n const bool = input.toLowerCase();\n if (['true', '1'].includes(bool)) {\n return true;\n } else if (['false', '0'].includes(bool)) {\n return false;\n }\n throw new TypeError(`Invalid input for ${optionName}: \"${input}\"`);\n}\n\nfunction showUsage(\n optionList: DescribedOptionDefinition[],\n description: {header: string; content: string}[] = [],\n logger: OptionalLogger = console,\n) {\n const hide: string[] = [];\n let leftWidth = 35;\n let rightWidth = 70;\n optionList.forEach(({name, typeLabel, description, hidden}) => {\n if (hidden) {\n hide.push(name);\n }\n const text = template(`${name} ${typeLabel ?? ''}`);\n const lines = stripAnsi(text).split('\\n');\n for (const l of lines) {\n leftWidth = Math.max(leftWidth, l.length + 2);\n }\n const desc = stripAnsi(template(description ?? '')).split('\\n');\n for (const l of desc) {\n rightWidth = Math.max(rightWidth, l.length + 2);\n }\n });\n\n const sections: Section[] = [\n {\n optionList,\n reverseNameOrder: true, // Display --flag-name before -alias\n hide,\n tableOptions: {\n columns: [\n {name: 'option', width: leftWidth},\n {name: 'description', width: rightWidth},\n ],\n noTrim: true,\n },\n },\n ];\n\n if (description) {\n sections.unshift(...description);\n }\n\n logger.info?.(commandLineUsage(sections));\n}\n\ntype DescribedOptionDefinition = OptionDefinition & {\n // Additional fields recognized by command-line-usage\n description?: string;\n typeLabel?: string | undefined;\n hidden?: boolean | undefined;\n};\n"],"names":["options","v.object","v.instanceOfAbstractType","v.testOptional","t","name","v.deepPartial","v.parse","description","stripAnsi"],"mappings":"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"}
|
package/out/zero/package.json.js
CHANGED
|
@@ -38,8 +38,10 @@ async function main() {
|
|
|
38
38
|
{
|
|
39
39
|
envNamePrefix: ZERO_ENV_VAR_PREFIX,
|
|
40
40
|
// TODO: This may no longer be necessary since multi-tenant was removed.
|
|
41
|
-
allowPartial: true
|
|
41
|
+
allowPartial: true,
|
|
42
42
|
// required by server/runner/config.ts
|
|
43
|
+
// Let the spawned zero-cache process emit deprecation warnings
|
|
44
|
+
emitDeprecationWarnings: false
|
|
43
45
|
}
|
|
44
46
|
);
|
|
45
47
|
const lc = createLogContext(config);
|
|
@@ -53,13 +55,15 @@ async function main() {
|
|
|
53
55
|
{
|
|
54
56
|
envNamePrefix: ZERO_ENV_VAR_PREFIX,
|
|
55
57
|
allowUnknown: true,
|
|
56
|
-
includeDefaults: false
|
|
58
|
+
includeDefaults: false,
|
|
59
|
+
emitDeprecationWarnings: false
|
|
57
60
|
}
|
|
58
61
|
);
|
|
59
62
|
const { env: zeroCacheEnv } = parseOptionsAdvanced(zeroOptions, {
|
|
60
63
|
envNamePrefix: ZERO_ENV_VAR_PREFIX,
|
|
61
64
|
allowUnknown: true,
|
|
62
|
-
includeDefaults: false
|
|
65
|
+
includeDefaults: false,
|
|
66
|
+
emitDeprecationWarnings: false
|
|
63
67
|
});
|
|
64
68
|
let permissionsProcess;
|
|
65
69
|
let zeroCacheProcess;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zero-cache-dev.js","sources":["../../../src/zero-cache-dev.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport '../../shared/src/dotenv.ts';\n\nimport {resolver} from '@rocicorp/resolver';\nimport {watch} from 'chokidar';\nimport {spawn, type ChildProcess} from 'node:child_process';\nimport {createLogContext} from '../../shared/src/logging.ts';\nimport {parseOptionsAdvanced} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {\n ZERO_ENV_VAR_PREFIX,\n zeroOptions,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {deployPermissionsOptions} from '../../zero-cache/src/scripts/permissions.ts';\n\nconst deployPermissionsScript = 'zero-deploy-permissions';\nconst zeroCacheScript = 'zero-cache';\n\nfunction killProcess(childProcess: ChildProcess | undefined) {\n if (!childProcess || childProcess.exitCode !== null) {\n return Promise.resolve();\n }\n const {resolve, promise} = resolver();\n childProcess.on('exit', resolve);\n // Use SIGQUIT in particular since this will cause\n // a fast zero-cache shutdown instead of a graceful drain.\n childProcess.kill('SIGQUIT');\n return promise;\n}\n\nasync function main() {\n const {config} = parseOptionsAdvanced(\n {\n schema: {\n path: {\n type: v.string().optional(),\n desc: ['Relative path to the file containing permissions.'],\n alias: 'p',\n deprecated: [\n 'Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth.',\n ],\n },\n },\n ...zeroOptions,\n },\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n // TODO: This may no longer be necessary since multi-tenant was removed.\n allowPartial: true, // required by server/runner/config.ts\n },\n );\n\n const lc = createLogContext(config);\n\n process.on('unhandledRejection', reason => {\n lc.error?.('Unexpected unhandled rejection.', reason);\n lc.error?.('Exiting');\n process.exit(-1);\n });\n\n // Parse options for each subprocess to get environment variables\n const {env: deployPermissionsEnv} = parseOptionsAdvanced(\n deployPermissionsOptions,\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n },\n );\n const {env: zeroCacheEnv} = parseOptionsAdvanced(zeroOptions, {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n });\n\n let permissionsProcess: ChildProcess | undefined;\n let zeroCacheProcess: ChildProcess | undefined;\n\n // Ensure child processes are killed when the main process exits\n process.on('exit', () => {\n permissionsProcess?.kill('SIGQUIT');\n zeroCacheProcess?.kill('SIGQUIT');\n });\n\n async function deployPermissions(): Promise<boolean> {\n if (config.upstream.type !== 'pg') {\n lc.warn?.(\n `Skipping permissions deployment for ${config.upstream.type} upstream`,\n );\n return true;\n }\n permissionsProcess?.removeAllListeners('exit');\n await killProcess(permissionsProcess);\n permissionsProcess = undefined;\n\n lc.info?.(`Running ${deployPermissionsScript}.`);\n permissionsProcess = spawn(deployPermissionsScript, [], {\n env: {...process.env, ...deployPermissionsEnv},\n stdio: 'inherit',\n shell: true,\n });\n\n const {promise: code, resolve} = resolver<number>();\n permissionsProcess.on('exit', resolve);\n if ((await code) === 0) {\n lc.info?.(`${deployPermissionsScript} completed successfully.`);\n return true;\n }\n lc.error?.(`Failed to deploy permissions from ${config.schema.path}.`);\n return false;\n }\n\n async function startZeroCache() {\n zeroCacheProcess?.removeAllListeners('exit');\n await killProcess(zeroCacheProcess);\n zeroCacheProcess = undefined;\n\n lc.info?.(\n `Running ${zeroCacheScript} at\\n\\n\\thttp://localhost:${config.port}\\n`,\n );\n const env: NodeJS.ProcessEnv = {\n // Set some low defaults so as to use fewer resources and not trip up,\n // e.g. developers sharing a database.\n ['ZERO_NUM_SYNC_WORKERS']: '3',\n ['ZERO_CVR_MAX_CONNS']: '6',\n ['ZERO_UPSTREAM_MAX_CONNS']: '6',\n\n // Default NODE_ENV to development mode.\n // @ts-ignore NODE_ENV is not always set. Please ignore error.\n ['NODE_ENV']: 'development',\n\n // But let the developer override any of these dev defaults.\n ...process.env,\n ...zeroCacheEnv,\n };\n zeroCacheProcess = spawn(zeroCacheScript, [], {\n env,\n stdio: 'inherit',\n shell: true,\n });\n zeroCacheProcess.on('exit', () => {\n lc.error?.(`${zeroCacheScript} exited. Exiting.`);\n process.exit(-1);\n });\n }\n\n async function deployPermissionsAndStartZeroCache() {\n if (await deployPermissions()) {\n await startZeroCache();\n }\n }\n\n if (config.schema.path) {\n if (config.query.url && config.mutate.url) {\n lc.error?.(\n 'Cannot use -p/--path/ZERO_SCHEMA_PATH flag when using ZERO_MUTATE_URL and ZERO_QUERY_URL.',\n );\n process.exit(-1);\n }\n\n await deployPermissionsAndStartZeroCache();\n\n // Watch for file changes\n const watcher = watch(config.schema.path, {\n ignoreInitial: true,\n awaitWriteFinish: {stabilityThreshold: 500, pollInterval: 100},\n });\n const onFileChange = async () => {\n lc.info?.(`Detected ${config.schema.path} change.`);\n await deployPermissions();\n };\n watcher.on('add', onFileChange);\n watcher.on('change', onFileChange);\n watcher.on('unlink', onFileChange);\n } else {\n await startZeroCache();\n }\n}\n\nvoid main();\n"],"names":["v.string"],"mappings":";;;;;;;;;;;AAgBA,MAAM,0BAA0B;AAChC,MAAM,kBAAkB;AAExB,SAAS,YAAY,cAAwC;AAC3D,MAAI,CAAC,gBAAgB,aAAa,aAAa,MAAM;AACnD,WAAO,QAAQ,QAAA;AAAA,EACjB;AACA,QAAM,EAAC,SAAS,QAAA,IAAW,SAAA;AAC3B,eAAa,GAAG,QAAQ,OAAO;AAG/B,eAAa,KAAK,SAAS;AAC3B,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,EAAC,WAAU;AAAA,IACf;AAAA,MACE,QAAQ;AAAA,QACN,MAAM;AAAA,UACJ,MAAMA,OAAE,EAAS,SAAA;AAAA,UACjB,MAAM,CAAC,mDAAmD;AAAA,UAC1D,OAAO;AAAA,UACP,YAAY;AAAA,YACV;AAAA,UAAA;AAAA,QACF;AAAA,MACF;AAAA,MAEF,GAAG;AAAA,IAAA;AAAA,IAEL;AAAA,MACE,eAAe;AAAA;AAAA,MAEf,cAAc;AAAA;AAAA,IAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"zero-cache-dev.js","sources":["../../../src/zero-cache-dev.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport '../../shared/src/dotenv.ts';\n\nimport {resolver} from '@rocicorp/resolver';\nimport {watch} from 'chokidar';\nimport {spawn, type ChildProcess} from 'node:child_process';\nimport {createLogContext} from '../../shared/src/logging.ts';\nimport {parseOptionsAdvanced} from '../../shared/src/options.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {\n ZERO_ENV_VAR_PREFIX,\n zeroOptions,\n} from '../../zero-cache/src/config/zero-config.ts';\nimport {deployPermissionsOptions} from '../../zero-cache/src/scripts/permissions.ts';\n\nconst deployPermissionsScript = 'zero-deploy-permissions';\nconst zeroCacheScript = 'zero-cache';\n\nfunction killProcess(childProcess: ChildProcess | undefined) {\n if (!childProcess || childProcess.exitCode !== null) {\n return Promise.resolve();\n }\n const {resolve, promise} = resolver();\n childProcess.on('exit', resolve);\n // Use SIGQUIT in particular since this will cause\n // a fast zero-cache shutdown instead of a graceful drain.\n childProcess.kill('SIGQUIT');\n return promise;\n}\n\nasync function main() {\n const {config} = parseOptionsAdvanced(\n {\n schema: {\n path: {\n type: v.string().optional(),\n desc: ['Relative path to the file containing permissions.'],\n alias: 'p',\n deprecated: [\n 'Permissions are deprecated and will be removed in an upcoming release. See: https://zero.rocicorp.dev/docs/auth.',\n ],\n },\n },\n ...zeroOptions,\n },\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n // TODO: This may no longer be necessary since multi-tenant was removed.\n allowPartial: true, // required by server/runner/config.ts\n // Let the spawned zero-cache process emit deprecation warnings\n emitDeprecationWarnings: false,\n },\n );\n\n const lc = createLogContext(config);\n\n process.on('unhandledRejection', reason => {\n lc.error?.('Unexpected unhandled rejection.', reason);\n lc.error?.('Exiting');\n process.exit(-1);\n });\n\n // Parse options for each subprocess to get environment variables\n const {env: deployPermissionsEnv} = parseOptionsAdvanced(\n deployPermissionsOptions,\n {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n },\n );\n const {env: zeroCacheEnv} = parseOptionsAdvanced(zeroOptions, {\n envNamePrefix: ZERO_ENV_VAR_PREFIX,\n allowUnknown: true,\n includeDefaults: false,\n emitDeprecationWarnings: false,\n });\n\n let permissionsProcess: ChildProcess | undefined;\n let zeroCacheProcess: ChildProcess | undefined;\n\n // Ensure child processes are killed when the main process exits\n process.on('exit', () => {\n permissionsProcess?.kill('SIGQUIT');\n zeroCacheProcess?.kill('SIGQUIT');\n });\n\n async function deployPermissions(): Promise<boolean> {\n if (config.upstream.type !== 'pg') {\n lc.warn?.(\n `Skipping permissions deployment for ${config.upstream.type} upstream`,\n );\n return true;\n }\n permissionsProcess?.removeAllListeners('exit');\n await killProcess(permissionsProcess);\n permissionsProcess = undefined;\n\n lc.info?.(`Running ${deployPermissionsScript}.`);\n permissionsProcess = spawn(deployPermissionsScript, [], {\n env: {...process.env, ...deployPermissionsEnv},\n stdio: 'inherit',\n shell: true,\n });\n\n const {promise: code, resolve} = resolver<number>();\n permissionsProcess.on('exit', resolve);\n if ((await code) === 0) {\n lc.info?.(`${deployPermissionsScript} completed successfully.`);\n return true;\n }\n lc.error?.(`Failed to deploy permissions from ${config.schema.path}.`);\n return false;\n }\n\n async function startZeroCache() {\n zeroCacheProcess?.removeAllListeners('exit');\n await killProcess(zeroCacheProcess);\n zeroCacheProcess = undefined;\n\n lc.info?.(\n `Running ${zeroCacheScript} at\\n\\n\\thttp://localhost:${config.port}\\n`,\n );\n const env: NodeJS.ProcessEnv = {\n // Set some low defaults so as to use fewer resources and not trip up,\n // e.g. developers sharing a database.\n ['ZERO_NUM_SYNC_WORKERS']: '3',\n ['ZERO_CVR_MAX_CONNS']: '6',\n ['ZERO_UPSTREAM_MAX_CONNS']: '6',\n\n // Default NODE_ENV to development mode.\n // @ts-ignore NODE_ENV is not always set. Please ignore error.\n ['NODE_ENV']: 'development',\n\n // But let the developer override any of these dev defaults.\n ...process.env,\n ...zeroCacheEnv,\n };\n zeroCacheProcess = spawn(zeroCacheScript, [], {\n env,\n stdio: 'inherit',\n shell: true,\n });\n zeroCacheProcess.on('exit', () => {\n lc.error?.(`${zeroCacheScript} exited. Exiting.`);\n process.exit(-1);\n });\n }\n\n async function deployPermissionsAndStartZeroCache() {\n if (await deployPermissions()) {\n await startZeroCache();\n }\n }\n\n if (config.schema.path) {\n if (config.query.url && config.mutate.url) {\n lc.error?.(\n 'Cannot use -p/--path/ZERO_SCHEMA_PATH flag when using ZERO_MUTATE_URL and ZERO_QUERY_URL.',\n );\n process.exit(-1);\n }\n\n await deployPermissionsAndStartZeroCache();\n\n // Watch for file changes\n const watcher = watch(config.schema.path, {\n ignoreInitial: true,\n awaitWriteFinish: {stabilityThreshold: 500, pollInterval: 100},\n });\n const onFileChange = async () => {\n lc.info?.(`Detected ${config.schema.path} change.`);\n await deployPermissions();\n };\n watcher.on('add', onFileChange);\n watcher.on('change', onFileChange);\n watcher.on('unlink', onFileChange);\n } else {\n await startZeroCache();\n }\n}\n\nvoid main();\n"],"names":["v.string"],"mappings":"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"}
|
|
@@ -6,6 +6,8 @@ import { type Config, type ParseOptions } from '../../../shared/src/options.ts';
|
|
|
6
6
|
import * as v from '../../../shared/src/valita.ts';
|
|
7
7
|
import { type NormalizedZeroConfig } from './normalize.ts';
|
|
8
8
|
export type { LogConfig } from '../../../otel/src/log-options.ts';
|
|
9
|
+
export declare const ZERO_ENV_VAR_PREFIX = "ZERO_";
|
|
10
|
+
export declare const DEFAULT_BACK_PRESSURE_THRESHOLD = 100000;
|
|
9
11
|
export declare const appOptions: {
|
|
10
12
|
id: {
|
|
11
13
|
type: v.Type<string>;
|
|
@@ -320,6 +322,10 @@ export declare const zeroOptions: {
|
|
|
320
322
|
type: v.Type<number>;
|
|
321
323
|
desc: string[];
|
|
322
324
|
};
|
|
325
|
+
backPressureThreshold: {
|
|
326
|
+
type: v.Type<number>;
|
|
327
|
+
desc: string[];
|
|
328
|
+
};
|
|
323
329
|
};
|
|
324
330
|
taskID: {
|
|
325
331
|
type: v.Optional<string>;
|
|
@@ -371,6 +377,10 @@ export declare const zeroOptions: {
|
|
|
371
377
|
type: v.Optional<string>;
|
|
372
378
|
desc: string[];
|
|
373
379
|
};
|
|
380
|
+
endpoint: {
|
|
381
|
+
type: v.Optional<string>;
|
|
382
|
+
desc: string[];
|
|
383
|
+
};
|
|
374
384
|
port: {
|
|
375
385
|
type: v.Optional<number>;
|
|
376
386
|
desc: string[];
|
|
@@ -453,7 +463,6 @@ export declare const zeroOptions: {
|
|
|
453
463
|
};
|
|
454
464
|
};
|
|
455
465
|
export type ZeroConfig = Config<typeof zeroOptions>;
|
|
456
|
-
export declare const ZERO_ENV_VAR_PREFIX = "ZERO_";
|
|
457
466
|
export declare function getZeroConfig(opts?: Omit<ParseOptions, 'envNamePrefix'>): ZeroConfig;
|
|
458
467
|
/**
|
|
459
468
|
* Same as {@link getZeroConfig}, with an additional check that the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,
|
|
1
|
+
{"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AASnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,SAAS,EAAC,MAAM,kCAAkC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAc3C,eAAO,MAAM,+BAA+B,SAAU,CAAC;AAEvD,eAAO,MAAM,UAAU;;;;;;;;;CA+CtB,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;CAwBxB,CAAC;AAEF,QAAA,MAAM,cAAc;;;;;;;;;;;;;CAgCnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,QAAA,MAAM,oBAAoB;;;;;;;;;CAczB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5D,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;CA4BhB,CAAC;AAsFF,kBAAkB;AAClB,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAKpD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;IAwCtB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuHlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6ChB,kBAAkB;;;;;;QASlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuRpB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgEnB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAIpD,wBAAgB,aAAa,CAC3B,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,UAAU,CAaZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,oBAAoB,CAItB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,SAAS,GACpD,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,WA4B7B;AAYD,wBAAgB,kBAAkB,SAEjC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { logOptions } from "../../../otel/src/log-options.js";
|
|
2
|
-
import { parseOptions } from "../../../shared/src/options.js";
|
|
2
|
+
import { flagToEnv, parseOptions } from "../../../shared/src/options.js";
|
|
3
3
|
import { literalUnion } from "../../../shared/src/valita.js";
|
|
4
4
|
import packageJson from "../../../zero/package.json.js";
|
|
5
5
|
import { runtimeDebugFlags } from "../../../zql/src/builder/debug-delegate.js";
|
|
@@ -7,6 +7,8 @@ import { singleProcessMode } from "../types/processes.js";
|
|
|
7
7
|
import { ALLOWED_APP_ID_CHARACTERS, INVALID_APP_ID_MESSAGE } from "../types/shards.js";
|
|
8
8
|
import { assertNormalized, isDevelopmentMode } from "./normalize.js";
|
|
9
9
|
import { array, string, number, boolean } from "@badrap/valita";
|
|
10
|
+
const ZERO_ENV_VAR_PREFIX = "ZERO_";
|
|
11
|
+
const DEFAULT_BACK_PRESSURE_THRESHOLD = 1e5;
|
|
10
12
|
const appOptions = {
|
|
11
13
|
id: {
|
|
12
14
|
type: string().default("zero").assert((id) => ALLOWED_APP_ID_CHARACTERS.test(id), INVALID_APP_ID_MESSAGE),
|
|
@@ -147,6 +149,7 @@ const authOptions = {
|
|
|
147
149
|
]
|
|
148
150
|
}
|
|
149
151
|
};
|
|
152
|
+
const makeDeprecationMessage = (flag) => `Use {bold ${flagToEnv(ZERO_ENV_VAR_PREFIX, flag)}} (or {bold --${flag}}) instead.`;
|
|
150
153
|
const makeMutatorQueryOptions = (replacement, suffix) => ({
|
|
151
154
|
url: {
|
|
152
155
|
type: array(string()).optional(),
|
|
@@ -192,14 +195,14 @@ const makeMutatorQueryOptions = (replacement, suffix) => ({
|
|
|
192
195
|
``,
|
|
193
196
|
`For full URLPattern syntax, see: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern`
|
|
194
197
|
],
|
|
195
|
-
...replacement ? { deprecated: [
|
|
198
|
+
...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-url`)] } : {}
|
|
196
199
|
},
|
|
197
200
|
apiKey: {
|
|
198
201
|
type: string().optional(),
|
|
199
202
|
desc: [
|
|
200
203
|
`An optional secret used to authorize zero-cache to call the API server handling writes.`
|
|
201
204
|
],
|
|
202
|
-
...replacement ? { deprecated: [
|
|
205
|
+
...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-api-key`)] } : {}
|
|
203
206
|
},
|
|
204
207
|
forwardCookies: {
|
|
205
208
|
type: boolean().default(false),
|
|
@@ -208,14 +211,14 @@ const makeMutatorQueryOptions = (replacement, suffix) => ({
|
|
|
208
211
|
`This is useful for passing authentication cookies to the API server.`,
|
|
209
212
|
`If false, cookies are not forwarded.`
|
|
210
213
|
],
|
|
211
|
-
...replacement ? { deprecated: [
|
|
214
|
+
...replacement ? { deprecated: [makeDeprecationMessage(`${replacement}-forward-cookies`)] } : {}
|
|
212
215
|
}
|
|
213
216
|
});
|
|
214
217
|
const mutateOptions = makeMutatorQueryOptions(void 0, "push mutations");
|
|
215
|
-
const pushOptions = makeMutatorQueryOptions("mutate
|
|
218
|
+
const pushOptions = makeMutatorQueryOptions("mutate", "push mutations");
|
|
216
219
|
const queryOptions = makeMutatorQueryOptions(void 0, "send synced queries");
|
|
217
220
|
const getQueriesOptions = makeMutatorQueryOptions(
|
|
218
|
-
"query
|
|
221
|
+
"query",
|
|
219
222
|
"send synced queries"
|
|
220
223
|
);
|
|
221
224
|
const zeroOptions = {
|
|
@@ -446,6 +449,16 @@ const zeroOptions = {
|
|
|
446
449
|
`is received during this interval, the delay will be canceled and the takeover will happen`,
|
|
447
450
|
`immediately, since the incoming request indicates that the task is registered as a target.`
|
|
448
451
|
]
|
|
452
|
+
},
|
|
453
|
+
backPressureThreshold: {
|
|
454
|
+
type: number().default(DEFAULT_BACK_PRESSURE_THRESHOLD),
|
|
455
|
+
desc: [
|
|
456
|
+
`The maximum number of queued changes before back pressure is applied to the`,
|
|
457
|
+
`change source. When the queue exceeds this threshold, the change-streamer pauses`,
|
|
458
|
+
`consumption from upstream until the queue drops to 90% of the threshold.`,
|
|
459
|
+
``,
|
|
460
|
+
`Increasing this value may improve throughput at the cost of higher memory usage.`
|
|
461
|
+
]
|
|
449
462
|
}
|
|
450
463
|
},
|
|
451
464
|
taskID: {
|
|
@@ -544,6 +557,13 @@ const zeroOptions = {
|
|
|
544
557
|
`{bold view-syncers} receive this information from the {bold replication-manager}.`
|
|
545
558
|
]
|
|
546
559
|
},
|
|
560
|
+
endpoint: {
|
|
561
|
+
type: string().optional(),
|
|
562
|
+
desc: [
|
|
563
|
+
`The S3-compatible endpoint URL to use for the litestream backup. Only required for non-AWS services.`,
|
|
564
|
+
`The {bold replication-manager} and {bold view-syncers} must have the same endpoint.`
|
|
565
|
+
]
|
|
566
|
+
},
|
|
547
567
|
port: {
|
|
548
568
|
type: number().optional(),
|
|
549
569
|
desc: [
|
|
@@ -707,7 +727,6 @@ const zeroOptions = {
|
|
|
707
727
|
}
|
|
708
728
|
}
|
|
709
729
|
};
|
|
710
|
-
const ZERO_ENV_VAR_PREFIX = "ZERO_";
|
|
711
730
|
let loadedConfig;
|
|
712
731
|
function getZeroConfig(opts = {}) {
|
|
713
732
|
if (!loadedConfig || singleProcessMode()) {
|
|
@@ -758,6 +777,7 @@ function warnOnce(lc, msg) {
|
|
|
758
777
|
}
|
|
759
778
|
}
|
|
760
779
|
export {
|
|
780
|
+
DEFAULT_BACK_PRESSURE_THRESHOLD,
|
|
761
781
|
ZERO_ENV_VAR_PREFIX,
|
|
762
782
|
appOptions,
|
|
763
783
|
getNormalizedZeroConfig,
|