@rebasepro/types 0.10.0 → 0.10.1-canary.14e53ae
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/dist/controllers/client.d.ts +3 -1
- package/dist/controllers/data_driver.d.ts +29 -0
- package/dist/index.es.js +270 -1
- package/dist/index.es.js.map +1 -1
- package/dist/types/backend.d.ts +30 -1
- package/dist/types/channel_bus.d.ts +192 -0
- package/dist/types/collection_contract.d.ts +43 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/project_manifest.d.ts +336 -0
- package/dist/types/schema_version.d.ts +18 -0
- package/dist/types/storage_authorize.d.ts +74 -0
- package/package.json +1 -1
- package/src/controllers/client.ts +3 -2
- package/src/controllers/data_driver.ts +56 -0
- package/src/types/backend.ts +33 -1
- package/src/types/channel_bus.ts +202 -0
- package/src/types/collection_contract.ts +249 -0
- package/src/types/index.ts +5 -0
- package/src/types/policy.ts +25 -11
- package/src/types/project_manifest.ts +362 -0
- package/src/types/schema_version.ts +112 -0
- package/src/types/storage_authorize.ts +77 -0
|
@@ -391,11 +391,13 @@ export interface RebaseServerClient<DB = unknown> extends RebaseClient<DB> {
|
|
|
391
391
|
email: EmailService;
|
|
392
392
|
/**
|
|
393
393
|
* Execute raw SQL against the database. Always present server-side for SQL
|
|
394
|
-
* engines.
|
|
394
|
+
* engines. Values interpolated into the query should be passed via
|
|
395
|
+
* `params`, referenced as `$1`, `$2`, … placeholders in the query text.
|
|
395
396
|
*/
|
|
396
397
|
sql(query: string, options?: {
|
|
397
398
|
database?: string;
|
|
398
399
|
role?: string;
|
|
400
|
+
params?: unknown[];
|
|
399
401
|
}): Promise<Record<string, unknown>[]>;
|
|
400
402
|
}
|
|
401
403
|
/**
|
|
@@ -32,6 +32,35 @@ export interface VectorSearchParams {
|
|
|
32
32
|
/** Only return results within this distance threshold */
|
|
33
33
|
threshold?: number;
|
|
34
34
|
}
|
|
35
|
+
/** Rows returned for a plain / text-search list read when the client sends no `limit`. */
|
|
36
|
+
export declare const DEFAULT_LIST_LIMIT = 50;
|
|
37
|
+
/** Rows returned for a vector-search list read when the client sends no `limit`. */
|
|
38
|
+
export declare const DEFAULT_VECTOR_LIST_LIMIT = 10;
|
|
39
|
+
/** Hard ceiling clamped onto any client-supplied `limit`, on every surface. */
|
|
40
|
+
export declare const MAX_LIST_LIMIT = 1000;
|
|
41
|
+
/** Overridable bounds for {@link resolveClientListLimit}. */
|
|
42
|
+
export interface ListLimitBounds {
|
|
43
|
+
/** Default page size for plain and text-search reads. */
|
|
44
|
+
defaultLimit?: number;
|
|
45
|
+
/** Default page size for vector-search reads. */
|
|
46
|
+
vectorDefaultLimit?: number;
|
|
47
|
+
/** Upper bound clamped onto any client-supplied limit. */
|
|
48
|
+
maxLimit?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a client-supplied list `limit` into a safe, always-defined value.
|
|
52
|
+
*
|
|
53
|
+
* - A provided limit is coerced to an integer and clamped to `[1, maxLimit]`,
|
|
54
|
+
* so `0`, negatives, and absurd values can never bypass the cap.
|
|
55
|
+
* - An absent / blank / non-numeric limit falls back to the mode default:
|
|
56
|
+
* `vectorDefaultLimit` for a vector search, otherwise `defaultLimit`.
|
|
57
|
+
*
|
|
58
|
+
* The return is never `undefined` — no ingress that routes its client limit
|
|
59
|
+
* through this can produce an unbounded read.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolveClientListLimit(rawLimit: number | string | null | undefined, opts?: ListLimitBounds & {
|
|
62
|
+
vectorSearch?: boolean;
|
|
63
|
+
}): number;
|
|
35
64
|
/**
|
|
36
65
|
* @internal
|
|
37
66
|
*/
|
package/dist/index.es.js
CHANGED
|
@@ -416,6 +416,19 @@ function isBranchAdmin(admin) {
|
|
|
416
416
|
return !!admin && typeof admin.createBranch === "function";
|
|
417
417
|
}
|
|
418
418
|
//#endregion
|
|
419
|
+
//#region src/types/channel_bus.ts
|
|
420
|
+
/**
|
|
421
|
+
* Whether `setting` is an already-constructed transport rather than a request
|
|
422
|
+
* for a built-in one.
|
|
423
|
+
*
|
|
424
|
+
* Structural rather than nominal so that an instance from a *different copy* of
|
|
425
|
+
* `@rebasepro/types` — an entirely normal outcome of a separately versioned
|
|
426
|
+
* transport package — is still recognised.
|
|
427
|
+
*/
|
|
428
|
+
function isChannelBusInstance(setting) {
|
|
429
|
+
return typeof setting?.publish === "function";
|
|
430
|
+
}
|
|
431
|
+
//#endregion
|
|
419
432
|
//#region src/types/data_source.ts
|
|
420
433
|
/**
|
|
421
434
|
* The default data-source key, used when a collection does not name a
|
|
@@ -541,6 +554,262 @@ function isLazyComponentRef(ref) {
|
|
|
541
554
|
return typeof ref === "object" && ref !== null && "__rebaseLazy" in ref && ref.__rebaseLazy === true;
|
|
542
555
|
}
|
|
543
556
|
//#endregion
|
|
557
|
+
//#region src/types/project_manifest.ts
|
|
558
|
+
/**
|
|
559
|
+
* Version of the bundle *format* itself.
|
|
560
|
+
*
|
|
561
|
+
* Bumped only when the on-disk layout changes in a way an older runtime could
|
|
562
|
+
* not read. A runtime accepts any bundle whose `bundleFormat` is less than or
|
|
563
|
+
* equal to its own — old bundles keep booting on new runtimes, which is the
|
|
564
|
+
* whole point of separating the artifact from the engine.
|
|
565
|
+
*/
|
|
566
|
+
var BUNDLE_FORMAT_VERSION = 1;
|
|
567
|
+
/**
|
|
568
|
+
* The runtime contract major.
|
|
569
|
+
*
|
|
570
|
+
* Distinct from the `@rebasepro/server` package version: the package may release
|
|
571
|
+
* any number of minors and patches while this stays put. It changes only when
|
|
572
|
+
* the bundle/runtime contract breaks compatibility, and a project's
|
|
573
|
+
* `manifest.runtime` range is matched against *this*.
|
|
574
|
+
*/
|
|
575
|
+
var RUNTIME_CONTRACT_VERSION = 1;
|
|
576
|
+
/** Header carrying the schema version an SDK was generated from. */
|
|
577
|
+
var SCHEMA_VERSION_HEADER = "x-rebase-schema";
|
|
578
|
+
//#endregion
|
|
579
|
+
//#region src/types/collection_contract.ts
|
|
580
|
+
function isSerializedCollectionRef(value) {
|
|
581
|
+
return typeof value === "object" && value !== null && typeof value.__collectionRef === "string";
|
|
582
|
+
}
|
|
583
|
+
/** Depth limit for the walk — deep enough for real configs, finite for cyclic ones. */
|
|
584
|
+
var MAX_DEPTH = 64;
|
|
585
|
+
/**
|
|
586
|
+
* Resolve whatever a `target` thunk returns down to a collection.
|
|
587
|
+
*
|
|
588
|
+
* A target may be the collection, a module namespace (when the authoring file
|
|
589
|
+
* used `import * as`), or a default-export wrapper. All three appear in real
|
|
590
|
+
* projects, and the SDK generator already unwraps them the same way.
|
|
591
|
+
*/
|
|
592
|
+
function unwrapTarget(value) {
|
|
593
|
+
if (!value || typeof value !== "object") return void 0;
|
|
594
|
+
const candidate = value;
|
|
595
|
+
if (candidate.default || candidate.__esModule) {
|
|
596
|
+
const inner = candidate.default;
|
|
597
|
+
if (inner && typeof inner === "object") return inner;
|
|
598
|
+
}
|
|
599
|
+
if (candidate.properties) return value;
|
|
600
|
+
}
|
|
601
|
+
/** The identity a serialized reference uses. Slug first — it is the routing key. */
|
|
602
|
+
function refFor(collection) {
|
|
603
|
+
if (!collection) return void 0;
|
|
604
|
+
const withPath = collection;
|
|
605
|
+
return collection.slug || withPath.path || collection.name;
|
|
606
|
+
}
|
|
607
|
+
function toSerializable(value, seen, depth, state, key) {
|
|
608
|
+
if (depth > MAX_DEPTH) {
|
|
609
|
+
state.truncations++;
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
if (typeof value === "function") {
|
|
613
|
+
if (key === "target") try {
|
|
614
|
+
const ref = refFor(unwrapTarget(value()));
|
|
615
|
+
return ref ? { __collectionRef: ref } : void 0;
|
|
616
|
+
} catch {
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
return;
|
|
620
|
+
}
|
|
621
|
+
if (value === null || typeof value !== "object") return value;
|
|
622
|
+
if (value instanceof Date) return value.toISOString();
|
|
623
|
+
if (value instanceof RegExp) return value.source;
|
|
624
|
+
if (seen.has(value)) {
|
|
625
|
+
state.truncations++;
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
const cached = state.memo.get(value);
|
|
629
|
+
if (cached !== void 0) return cached;
|
|
630
|
+
seen.add(value);
|
|
631
|
+
const truncationsBefore = state.truncations;
|
|
632
|
+
const memoize = (result) => {
|
|
633
|
+
if (result !== void 0 && state.truncations === truncationsBefore) state.memo.set(value, result);
|
|
634
|
+
return result;
|
|
635
|
+
};
|
|
636
|
+
try {
|
|
637
|
+
if (Array.isArray(value)) {
|
|
638
|
+
const items = value.map((item) => toSerializable(item, seen, depth + 1, state)).filter((item) => item !== void 0);
|
|
639
|
+
return memoize(value.length > 0 && items.length === 0 ? void 0 : items);
|
|
640
|
+
}
|
|
641
|
+
if ("$$typeof" in value) return void 0;
|
|
642
|
+
const entries = Object.entries(value);
|
|
643
|
+
const out = {};
|
|
644
|
+
for (const [k, v] of entries) {
|
|
645
|
+
const converted = toSerializable(v, seen, depth + 1, state, k);
|
|
646
|
+
if (converted !== void 0) out[k] = converted;
|
|
647
|
+
}
|
|
648
|
+
if (entries.length > 0 && Object.keys(out).length === 0) return void 0;
|
|
649
|
+
return memoize(out);
|
|
650
|
+
} finally {
|
|
651
|
+
seen.delete(value);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
/**
|
|
655
|
+
* Serialize collections for transport over the contract endpoint.
|
|
656
|
+
*
|
|
657
|
+
* Sorted by slug so the output — and therefore the schema hash computed from it
|
|
658
|
+
* — does not depend on filesystem ordering.
|
|
659
|
+
*/
|
|
660
|
+
function serializeCollections(collections) {
|
|
661
|
+
return [...collections].sort((a, b) => String(a.slug ?? "").localeCompare(String(b.slug ?? ""))).map((collection) => toSerializable(collection, /* @__PURE__ */ new WeakSet(), 0, {
|
|
662
|
+
memo: /* @__PURE__ */ new WeakMap(),
|
|
663
|
+
truncations: 0
|
|
664
|
+
})).filter((c) => c !== void 0);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Rebuild collections received from a contract endpoint.
|
|
668
|
+
*
|
|
669
|
+
* Relation refs become real thunks resolving through the returned set, so
|
|
670
|
+
* downstream consumers — the SDK generator above all — see exactly the shape
|
|
671
|
+
* they would have seen had the collections been imported from source.
|
|
672
|
+
*
|
|
673
|
+
* A ref naming a collection that is not in the payload resolves to `undefined`
|
|
674
|
+
* rather than throwing: the generator already tolerates an unresolvable target
|
|
675
|
+
* by falling back to a permissive key type, and a partial contract should still
|
|
676
|
+
* produce a usable SDK.
|
|
677
|
+
*/
|
|
678
|
+
function deserializeCollections(payload) {
|
|
679
|
+
const collections = payload.filter((c) => typeof c === "object" && c !== null).map((c) => ({ ...c }));
|
|
680
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
681
|
+
for (const collection of collections) {
|
|
682
|
+
const ref = refFor(collection);
|
|
683
|
+
if (ref) bySlug.set(ref, collection);
|
|
684
|
+
}
|
|
685
|
+
const rehydrate = (value, depth) => {
|
|
686
|
+
if (depth > MAX_DEPTH || !value || typeof value !== "object") return;
|
|
687
|
+
if (Array.isArray(value)) {
|
|
688
|
+
for (const item of value) rehydrate(item, depth + 1);
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
const record = value;
|
|
692
|
+
for (const [key, child] of Object.entries(record)) {
|
|
693
|
+
if (key === "target" && isSerializedCollectionRef(child)) {
|
|
694
|
+
const slug = child.__collectionRef;
|
|
695
|
+
record.target = () => bySlug.get(slug);
|
|
696
|
+
continue;
|
|
697
|
+
}
|
|
698
|
+
rehydrate(child, depth + 1);
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
for (const collection of collections) rehydrate(collection, 0);
|
|
702
|
+
return collections;
|
|
703
|
+
}
|
|
704
|
+
//#endregion
|
|
705
|
+
//#region src/types/schema_version.ts
|
|
706
|
+
/**
|
|
707
|
+
* The schema version stamp.
|
|
708
|
+
*
|
|
709
|
+
* One function, used in three places that must agree or the whole drift-detection
|
|
710
|
+
* story is noise: `rebase build` writes it into a bundle manifest, the runtime
|
|
711
|
+
* serves it from the contract endpoint, and a generated SDK records the value it
|
|
712
|
+
* was built from. If any two of those computed it differently, every client would
|
|
713
|
+
* look permanently out of date.
|
|
714
|
+
*
|
|
715
|
+
* It covers **collections only** — the client's contract is the shape of the
|
|
716
|
+
* data, so editing a hook or a server function must not invalidate every SDK in
|
|
717
|
+
* every repository. That is a deliberate narrowing, not an oversight.
|
|
718
|
+
*/
|
|
719
|
+
/** Stable stringify: object keys sorted at every level, so key order cannot alter the hash. */
|
|
720
|
+
function canonicalize(value) {
|
|
721
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
|
|
722
|
+
if (Array.isArray(value)) return `[${value.map(canonicalize).join(",")}]`;
|
|
723
|
+
return `{${Object.entries(value).filter(([, v]) => v !== void 0).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([k, v]) => `${JSON.stringify(k)}:${canonicalize(v)}`).join(",")}}`;
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Reduce a collection to the parts a generated client is actually built from.
|
|
727
|
+
*
|
|
728
|
+
* The version answers one question — "is this SDK stale?" — so it must change
|
|
729
|
+
* exactly when the generated types could change, and never otherwise. Hashing a
|
|
730
|
+
* whole collection fails both halves of that:
|
|
731
|
+
*
|
|
732
|
+
* - Security rules, callbacks, icons, groups and UI settings do not appear in a
|
|
733
|
+
* generated client, so including them reports perfectly current SDKs as stale.
|
|
734
|
+
* - Worse, they are not stable *inputs*. The runtime applies default security
|
|
735
|
+
* rules when it loads collections, so the same source hashed before and after
|
|
736
|
+
* loading produced two different answers — a build-time stamp that could never
|
|
737
|
+
* match the server that served it.
|
|
738
|
+
*
|
|
739
|
+
* Codegen reads the slug (for the `Database` key and type names), the properties,
|
|
740
|
+
* and the relations. That is the projection.
|
|
741
|
+
*/
|
|
742
|
+
function projectForCodegen(collection) {
|
|
743
|
+
const source = collection;
|
|
744
|
+
return {
|
|
745
|
+
slug: collection.slug ?? source.path,
|
|
746
|
+
properties: collection.properties,
|
|
747
|
+
relations: source.relations,
|
|
748
|
+
engine: source.engine,
|
|
749
|
+
dataSource: source.dataSource,
|
|
750
|
+
subcollections: source.subcollections?.map(projectForCodegen)
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Compute the canonical string a schema version hashes.
|
|
755
|
+
*
|
|
756
|
+
* Exposed separately so the hashing itself can differ by environment: Node has
|
|
757
|
+
* `crypto`, and callers without it can still compare canonical forms directly.
|
|
758
|
+
*/
|
|
759
|
+
function canonicalSchemaPayload(collections) {
|
|
760
|
+
return canonicalize(serializeCollections(collections).map((collection) => projectForCodegen(collection)));
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* A short, non-cryptographic digest of the canonical payload.
|
|
764
|
+
*
|
|
765
|
+
* FNV-1a style, 64 bits, as two 32-bit halves. This is an identity, not a
|
|
766
|
+
* security boundary: nothing trusts a schema version to prove anything, it only
|
|
767
|
+
* answers "is this the same schema as before". A hand-rolled hash keeps this
|
|
768
|
+
* module free of `node:crypto`, so the identical function runs in the browser,
|
|
769
|
+
* in the CLI, and in the runtime — which is the property that actually matters.
|
|
770
|
+
*/
|
|
771
|
+
function computeSchemaVersion(collections) {
|
|
772
|
+
const payload = canonicalSchemaPayload(collections);
|
|
773
|
+
let h1 = 2166136261;
|
|
774
|
+
let h2 = 16777619;
|
|
775
|
+
for (let i = 0; i < payload.length; i++) {
|
|
776
|
+
const code = payload.charCodeAt(i);
|
|
777
|
+
h1 ^= code;
|
|
778
|
+
h1 = h1 + ((h1 << 1) + (h1 << 4) + (h1 << 7) + (h1 << 8) + (h1 << 24)) >>> 0;
|
|
779
|
+
h2 ^= code + i;
|
|
780
|
+
h2 = h2 + ((h2 << 1) + (h2 << 5) + (h2 << 9) + (h2 << 15) + (h2 << 24)) >>> 0;
|
|
781
|
+
}
|
|
782
|
+
const hex = (n) => n.toString(16).padStart(8, "0");
|
|
783
|
+
return `v1:${hex(h1)}${hex(h2)}`;
|
|
784
|
+
}
|
|
785
|
+
//#endregion
|
|
786
|
+
//#region src/controllers/data_driver.ts
|
|
787
|
+
/** Rows returned for a plain / text-search list read when the client sends no `limit`. */
|
|
788
|
+
var DEFAULT_LIST_LIMIT = 50;
|
|
789
|
+
/** Rows returned for a vector-search list read when the client sends no `limit`. */
|
|
790
|
+
var DEFAULT_VECTOR_LIST_LIMIT = 10;
|
|
791
|
+
/** Hard ceiling clamped onto any client-supplied `limit`, on every surface. */
|
|
792
|
+
var MAX_LIST_LIMIT = 1e3;
|
|
793
|
+
/**
|
|
794
|
+
* Resolve a client-supplied list `limit` into a safe, always-defined value.
|
|
795
|
+
*
|
|
796
|
+
* - A provided limit is coerced to an integer and clamped to `[1, maxLimit]`,
|
|
797
|
+
* so `0`, negatives, and absurd values can never bypass the cap.
|
|
798
|
+
* - An absent / blank / non-numeric limit falls back to the mode default:
|
|
799
|
+
* `vectorDefaultLimit` for a vector search, otherwise `defaultLimit`.
|
|
800
|
+
*
|
|
801
|
+
* The return is never `undefined` — no ingress that routes its client limit
|
|
802
|
+
* through this can produce an unbounded read.
|
|
803
|
+
*/
|
|
804
|
+
function resolveClientListLimit(rawLimit, opts = {}) {
|
|
805
|
+
const maxLimit = opts.maxLimit ?? 1e3;
|
|
806
|
+
if (rawLimit != null && String(rawLimit).trim() !== "") {
|
|
807
|
+
const parsed = typeof rawLimit === "number" ? rawLimit : parseInt(String(rawLimit), 10);
|
|
808
|
+
if (Number.isFinite(parsed)) return Math.min(Math.max(1, Math.floor(parsed)), maxLimit);
|
|
809
|
+
}
|
|
810
|
+
return opts.vectorSearch ? opts.vectorDefaultLimit ?? 10 : opts.defaultLimit ?? 50;
|
|
811
|
+
}
|
|
812
|
+
//#endregion
|
|
544
813
|
//#region src/controllers/storage.ts
|
|
545
814
|
/**
|
|
546
815
|
* Path prefix that marks an object as **public**. Files stored under this
|
|
@@ -568,6 +837,6 @@ function isPublicStoragePath(path) {
|
|
|
568
837
|
return p.startsWith("public/") || p.startsWith(`default/public/`);
|
|
569
838
|
}
|
|
570
839
|
//#endregion
|
|
571
|
-
export { ALL_WHERE_FILTER_OPS, ANONYMOUS_USER_ID, CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_STORAGE_SOURCE_KEY, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MONGODB_CAPABILITIES, NULL_OPS, POSTGRES_CAPABILITIES, PUBLIC_STORAGE_PREFIX, REST_TO_CANONICAL, RebaseApiError, RebaseClientError, Vector, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isDocumentAdmin, isFirebaseCollectionConfig, isLazyComponentRef, isMongoDBCollectionConfig, isPostgresCollectionConfig, isPublicStoragePath, isSQLAdmin, isSchemaAdmin, policy, registerDataSourceCapabilities, toCanonicalOp };
|
|
840
|
+
export { ALL_WHERE_FILTER_OPS, ANONYMOUS_USER_ID, BUNDLE_FORMAT_VERSION, CANONICAL_TO_REST, DEFAULT_CAPABILITIES, DEFAULT_DATA_SOURCE_KEY, DEFAULT_LIST_LIMIT, DEFAULT_STORAGE_SOURCE_KEY, DEFAULT_VECTOR_LIST_LIMIT, EntityReference, EntityRelation, FIREBASE_CAPABILITIES, GeoPoint, MAX_LIST_LIMIT, MONGODB_CAPABILITIES, NULL_OPS, POSTGRES_CAPABILITIES, PUBLIC_STORAGE_PREFIX, REST_TO_CANONICAL, RUNTIME_CONTRACT_VERSION, RebaseApiError, RebaseClientError, SCHEMA_VERSION_HEADER, Vector, canonicalSchemaPayload, computeSchemaVersion, deserializeCollections, getCollectionDataPath, getDataSourceCapabilities, getDeclaredSubcollections, isBranchAdmin, isChannelBusInstance, isDocumentAdmin, isFirebaseCollectionConfig, isLazyComponentRef, isMongoDBCollectionConfig, isPostgresCollectionConfig, isPublicStoragePath, isSQLAdmin, isSchemaAdmin, isSerializedCollectionRef, policy, registerDataSourceCapabilities, resolveClientListLimit, serializeCollections, toCanonicalOp };
|
|
572
841
|
|
|
573
842
|
//# sourceMappingURL=index.es.js.map
|