fauxqs 2.4.0 → 2.4.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/README.md +129 -0
- package/dist/app.d.ts +15 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +75 -6
- package/dist/app.js.map +1 -1
- package/dist/s3/s3Store.d.ts +1 -1
- package/dist/s3/s3Store.d.ts.map +1 -1
- package/dist/s3/s3Store.js +3 -0
- package/dist/s3/s3Store.js.map +1 -1
- package/dist/server.js +60 -0
- package/dist/server.js.map +1 -1
- package/dist/sns/actions/publish.d.ts.map +1 -1
- package/dist/sns/actions/publish.js +6 -2
- package/dist/sns/actions/publish.js.map +1 -1
- package/dist/sns/snsStore.d.ts +1 -0
- package/dist/sns/snsStore.d.ts.map +1 -1
- package/dist/sns/snsStore.js +6 -0
- package/dist/sns/snsStore.js.map +1 -1
- package/dist/sqs/sqsStore.d.ts.map +1 -1
- package/dist/sqs/sqsStore.js +3 -0
- package/dist/sqs/sqsStore.js.map +1 -1
- package/dist/tenant/tenantManager.d.ts +79 -0
- package/dist/tenant/tenantManager.d.ts.map +1 -0
- package/dist/tenant/tenantManager.js +533 -0
- package/dist/tenant/tenantManager.js.map +1 -0
- package/dist/tenant/tenantTypes.d.ts +26 -0
- package/dist/tenant/tenantTypes.d.ts.map +1 -0
- package/dist/tenant/tenantTypes.js +6 -0
- package/dist/tenant/tenantTypes.js.map +1 -0
- package/dist/tenant/trackedStores.d.ts +93 -0
- package/dist/tenant/trackedStores.d.ts.map +1 -0
- package/dist/tenant/trackedStores.js +122 -0
- package/dist/tenant/trackedStores.js.map +1 -0
- package/dist/tenant/usageTracker.d.ts +40 -0
- package/dist/tenant/usageTracker.d.ts.map +1 -0
- package/dist/tenant/usageTracker.js +87 -0
- package/dist/tenant/usageTracker.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracked store subclasses for multi-tenant usage tracking.
|
|
3
|
+
*
|
|
4
|
+
* These override lookup methods to call `usageTracker.touch()` on every access.
|
|
5
|
+
* When tenant management is disabled, the base store classes are used directly —
|
|
6
|
+
* no tenant code runs on the hot path.
|
|
7
|
+
*
|
|
8
|
+
* MAINTENANCE: if a new public method is added to SqsStore, SnsStore, or S3Store
|
|
9
|
+
* that represents a "usage" of a resource (queue lookup, topic lookup, bucket
|
|
10
|
+
* operation), add a corresponding override here. The base store classes have a
|
|
11
|
+
* NOTE comment reminding contributors of this.
|
|
12
|
+
*/
|
|
13
|
+
import { SqsStore } from "../sqs/sqsStore.ts";
|
|
14
|
+
import type { SqsQueue } from "../sqs/sqsStore.ts";
|
|
15
|
+
import { SnsStore } from "../sns/snsStore.ts";
|
|
16
|
+
import type { SnsTopic } from "../sns/snsTypes.ts";
|
|
17
|
+
import { S3Store } from "../s3/s3Store.ts";
|
|
18
|
+
import type { S3Object, ChecksumAlgorithm } from "../s3/s3Types.ts";
|
|
19
|
+
import type { UsageTracker } from "./usageTracker.ts";
|
|
20
|
+
/**
|
|
21
|
+
* SqsStore subclass that touches the usage tracker on every queue lookup.
|
|
22
|
+
* Used only when tenant management is enabled — otherwise plain SqsStore is used.
|
|
23
|
+
*/
|
|
24
|
+
export declare class TrackedSqsStore extends SqsStore {
|
|
25
|
+
private readonly tracker;
|
|
26
|
+
constructor(tracker: UsageTracker);
|
|
27
|
+
getQueue(url: string): SqsQueue | undefined;
|
|
28
|
+
getQueueByName(name: string): SqsQueue | undefined;
|
|
29
|
+
getQueueByArn(arn: string): SqsQueue | undefined;
|
|
30
|
+
listQueues(prefix?: string, maxResults?: number, nextToken?: string): {
|
|
31
|
+
queues: SqsQueue[];
|
|
32
|
+
nextToken?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* SnsStore subclass that touches the usage tracker on topic lookup.
|
|
37
|
+
*/
|
|
38
|
+
export declare class TrackedSnsStore extends SnsStore {
|
|
39
|
+
private readonly tracker;
|
|
40
|
+
constructor(tracker: UsageTracker);
|
|
41
|
+
getTopic(arn: string): SnsTopic | undefined;
|
|
42
|
+
listTopics(nextToken?: string): {
|
|
43
|
+
topics: SnsTopic[];
|
|
44
|
+
nextToken?: string;
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* S3Store subclass that touches the usage tracker on bucket operations.
|
|
49
|
+
* Only methods that represent real "usage" of a bucket are overridden.
|
|
50
|
+
* uploadPart is excluded — createMultipartUpload and completeMultipartUpload
|
|
51
|
+
* cover the lifecycle, and uploadPart can be called thousands of times per object.
|
|
52
|
+
*/
|
|
53
|
+
export declare class TrackedS3Store extends S3Store {
|
|
54
|
+
private readonly tracker;
|
|
55
|
+
constructor(tracker: UsageTracker);
|
|
56
|
+
putObject(bucket: string, key: string, body: Buffer, contentType?: string, metadata?: Record<string, string>, systemMetadata?: {
|
|
57
|
+
contentLanguage?: string;
|
|
58
|
+
contentDisposition?: string;
|
|
59
|
+
cacheControl?: string;
|
|
60
|
+
contentEncoding?: string;
|
|
61
|
+
}, checksumData?: {
|
|
62
|
+
algorithm: ChecksumAlgorithm;
|
|
63
|
+
value: string;
|
|
64
|
+
type: "FULL_OBJECT" | "COMPOSITE";
|
|
65
|
+
partChecksums?: string[];
|
|
66
|
+
}): S3Object;
|
|
67
|
+
getObject(bucket: string, key: string): S3Object;
|
|
68
|
+
deleteObject(bucket: string, key: string): void;
|
|
69
|
+
headObject(bucket: string, key: string): S3Object;
|
|
70
|
+
listObjects(bucket: string, options?: {
|
|
71
|
+
prefix?: string;
|
|
72
|
+
delimiter?: string;
|
|
73
|
+
maxKeys?: number;
|
|
74
|
+
startAfter?: string;
|
|
75
|
+
marker?: string;
|
|
76
|
+
}): {
|
|
77
|
+
objects: S3Object[];
|
|
78
|
+
commonPrefixes: string[];
|
|
79
|
+
isTruncated: boolean;
|
|
80
|
+
};
|
|
81
|
+
renameObject(bucket: string, sourceKey: string, destKey: string): void;
|
|
82
|
+
createMultipartUpload(bucket: string, key: string, contentType?: string, metadata?: Record<string, string>, systemMetadata?: {
|
|
83
|
+
contentLanguage?: string;
|
|
84
|
+
contentDisposition?: string;
|
|
85
|
+
cacheControl?: string;
|
|
86
|
+
contentEncoding?: string;
|
|
87
|
+
}, checksumAlgorithm?: ChecksumAlgorithm): string;
|
|
88
|
+
completeMultipartUpload(uploadId: string, partSpecs: {
|
|
89
|
+
partNumber: number;
|
|
90
|
+
etag: string;
|
|
91
|
+
}[]): S3Object;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=trackedStores.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackedStores.d.ts","sourceRoot":"","sources":["../../src/tenant/trackedStores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracked store subclasses for multi-tenant usage tracking.
|
|
3
|
+
*
|
|
4
|
+
* These override lookup methods to call `usageTracker.touch()` on every access.
|
|
5
|
+
* When tenant management is disabled, the base store classes are used directly —
|
|
6
|
+
* no tenant code runs on the hot path.
|
|
7
|
+
*
|
|
8
|
+
* MAINTENANCE: if a new public method is added to SqsStore, SnsStore, or S3Store
|
|
9
|
+
* that represents a "usage" of a resource (queue lookup, topic lookup, bucket
|
|
10
|
+
* operation), add a corresponding override here. The base store classes have a
|
|
11
|
+
* NOTE comment reminding contributors of this.
|
|
12
|
+
*/
|
|
13
|
+
import { SqsStore } from "../sqs/sqsStore.js";
|
|
14
|
+
import { SnsStore } from "../sns/snsStore.js";
|
|
15
|
+
import { S3Store } from "../s3/s3Store.js";
|
|
16
|
+
/**
|
|
17
|
+
* SqsStore subclass that touches the usage tracker on every queue lookup.
|
|
18
|
+
* Used only when tenant management is enabled — otherwise plain SqsStore is used.
|
|
19
|
+
*/
|
|
20
|
+
export class TrackedSqsStore extends SqsStore {
|
|
21
|
+
tracker;
|
|
22
|
+
constructor(tracker) {
|
|
23
|
+
super();
|
|
24
|
+
this.tracker = tracker;
|
|
25
|
+
}
|
|
26
|
+
getQueue(url) {
|
|
27
|
+
const queue = super.getQueue(url);
|
|
28
|
+
if (queue)
|
|
29
|
+
this.tracker.touch(queue.name);
|
|
30
|
+
return queue;
|
|
31
|
+
}
|
|
32
|
+
getQueueByName(name) {
|
|
33
|
+
const queue = super.getQueueByName(name);
|
|
34
|
+
if (queue)
|
|
35
|
+
this.tracker.touch(queue.name);
|
|
36
|
+
return queue;
|
|
37
|
+
}
|
|
38
|
+
getQueueByArn(arn) {
|
|
39
|
+
const queue = super.getQueueByArn(arn);
|
|
40
|
+
if (queue)
|
|
41
|
+
this.tracker.touch(queue.name);
|
|
42
|
+
return queue;
|
|
43
|
+
}
|
|
44
|
+
listQueues(prefix, maxResults, nextToken) {
|
|
45
|
+
const result = super.listQueues(prefix, maxResults, nextToken);
|
|
46
|
+
for (const queue of result.queues) {
|
|
47
|
+
this.tracker.touch(queue.name);
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* SnsStore subclass that touches the usage tracker on topic lookup.
|
|
54
|
+
*/
|
|
55
|
+
export class TrackedSnsStore extends SnsStore {
|
|
56
|
+
tracker;
|
|
57
|
+
constructor(tracker) {
|
|
58
|
+
super();
|
|
59
|
+
this.tracker = tracker;
|
|
60
|
+
}
|
|
61
|
+
getTopic(arn) {
|
|
62
|
+
const topic = super.getTopic(arn);
|
|
63
|
+
if (topic)
|
|
64
|
+
this.tracker.touch(topic.name);
|
|
65
|
+
return topic;
|
|
66
|
+
}
|
|
67
|
+
listTopics(nextToken) {
|
|
68
|
+
const result = super.listTopics(nextToken);
|
|
69
|
+
for (const topic of result.topics) {
|
|
70
|
+
this.tracker.touch(topic.name);
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* S3Store subclass that touches the usage tracker on bucket operations.
|
|
77
|
+
* Only methods that represent real "usage" of a bucket are overridden.
|
|
78
|
+
* uploadPart is excluded — createMultipartUpload and completeMultipartUpload
|
|
79
|
+
* cover the lifecycle, and uploadPart can be called thousands of times per object.
|
|
80
|
+
*/
|
|
81
|
+
export class TrackedS3Store extends S3Store {
|
|
82
|
+
tracker;
|
|
83
|
+
constructor(tracker) {
|
|
84
|
+
super();
|
|
85
|
+
this.tracker = tracker;
|
|
86
|
+
}
|
|
87
|
+
putObject(bucket, key, body, contentType, metadata, systemMetadata, checksumData) {
|
|
88
|
+
this.tracker.touch(bucket);
|
|
89
|
+
return super.putObject(bucket, key, body, contentType, metadata, systemMetadata, checksumData);
|
|
90
|
+
}
|
|
91
|
+
getObject(bucket, key) {
|
|
92
|
+
this.tracker.touch(bucket);
|
|
93
|
+
return super.getObject(bucket, key);
|
|
94
|
+
}
|
|
95
|
+
deleteObject(bucket, key) {
|
|
96
|
+
this.tracker.touch(bucket);
|
|
97
|
+
super.deleteObject(bucket, key);
|
|
98
|
+
}
|
|
99
|
+
headObject(bucket, key) {
|
|
100
|
+
this.tracker.touch(bucket);
|
|
101
|
+
return super.headObject(bucket, key);
|
|
102
|
+
}
|
|
103
|
+
listObjects(bucket, options) {
|
|
104
|
+
this.tracker.touch(bucket);
|
|
105
|
+
return super.listObjects(bucket, options);
|
|
106
|
+
}
|
|
107
|
+
renameObject(bucket, sourceKey, destKey) {
|
|
108
|
+
this.tracker.touch(bucket);
|
|
109
|
+
super.renameObject(bucket, sourceKey, destKey);
|
|
110
|
+
}
|
|
111
|
+
createMultipartUpload(bucket, key, contentType, metadata, systemMetadata, checksumAlgorithm) {
|
|
112
|
+
this.tracker.touch(bucket);
|
|
113
|
+
return super.createMultipartUpload(bucket, key, contentType, metadata, systemMetadata, checksumAlgorithm);
|
|
114
|
+
}
|
|
115
|
+
completeMultipartUpload(uploadId, partSpecs) {
|
|
116
|
+
const upload = this.multipartUploads.get(uploadId);
|
|
117
|
+
if (upload)
|
|
118
|
+
this.tracker.touch(upload.bucket);
|
|
119
|
+
return super.completeMultipartUpload(uploadId, partSpecs);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=trackedStores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trackedStores.js","sourceRoot":"","sources":["../../src/tenant/trackedStores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export interface UsageEntry {
|
|
2
|
+
lastUsedMs: number;
|
|
3
|
+
/** Explicit prefix this resource belongs to, or null if not tenant-managed. */
|
|
4
|
+
prefix: string | null;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Tracks last-used timestamps and explicit prefix ownership for resources.
|
|
8
|
+
* Designed to be wired into stores via an optional field — when undefined,
|
|
9
|
+
* the optional chaining `store.usageTracker?.touch()` is a single falsy check.
|
|
10
|
+
*/
|
|
11
|
+
export declare class UsageTracker {
|
|
12
|
+
private entries;
|
|
13
|
+
/** Update the last-used timestamp for an already-registered resource. No-op if not registered. */
|
|
14
|
+
touch(name: string): void;
|
|
15
|
+
/** Register a resource with an explicit prefix. Also sets lastUsedMs to now. */
|
|
16
|
+
register(name: string, prefix: string | null): void;
|
|
17
|
+
/** Remove a resource from tracking. */
|
|
18
|
+
delete(name: string): void;
|
|
19
|
+
/** Get the entry for a resource, or undefined if not tracked. */
|
|
20
|
+
get(name: string): UsageEntry | undefined;
|
|
21
|
+
/** Number of tracked resources. */
|
|
22
|
+
get size(): number;
|
|
23
|
+
/**
|
|
24
|
+
* Iterate entries starting after `cursor`. Returns up to `budget` entries.
|
|
25
|
+
* When the end is reached, wraps around to the beginning.
|
|
26
|
+
* Returns the entries visited and whether a full cycle was completed.
|
|
27
|
+
*/
|
|
28
|
+
scan(cursor: string | undefined, budget: number): {
|
|
29
|
+
visited: Array<[string, UsageEntry]>;
|
|
30
|
+
nextCursor: string | undefined;
|
|
31
|
+
wrapped: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** Get all entries — primarily for listing/inspection. */
|
|
34
|
+
allEntries(): ReadonlyMap<string, UsageEntry>;
|
|
35
|
+
/** Return the next key after `name` in insertion order, or undefined if at end. */
|
|
36
|
+
nextAfter(name: string): string | undefined;
|
|
37
|
+
/** Clear all entries. */
|
|
38
|
+
clear(): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=usageTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usageTracker.d.ts","sourceRoot":"","sources":["../../src/tenant/usageTracker.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAiC;IAEhD,kGAAkG;IAClG,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOzB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAInD,uCAAuC;IACvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI1B,iEAAiE;IACjE,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAIzC,mCAAmC;IACnC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;OAIG;IACH,IAAI,CACF,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,MAAM,GACb;QAAE,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE;IAiC7F,0DAA0D;IAC1D,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC;IAI7C,mFAAmF;IACnF,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAS3C,yBAAyB;IACzB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks last-used timestamps and explicit prefix ownership for resources.
|
|
3
|
+
* Designed to be wired into stores via an optional field — when undefined,
|
|
4
|
+
* the optional chaining `store.usageTracker?.touch()` is a single falsy check.
|
|
5
|
+
*/
|
|
6
|
+
export class UsageTracker {
|
|
7
|
+
entries = new Map();
|
|
8
|
+
/** Update the last-used timestamp for an already-registered resource. No-op if not registered. */
|
|
9
|
+
touch(name) {
|
|
10
|
+
const entry = this.entries.get(name);
|
|
11
|
+
if (entry) {
|
|
12
|
+
entry.lastUsedMs = Date.now();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Register a resource with an explicit prefix. Also sets lastUsedMs to now. */
|
|
16
|
+
register(name, prefix) {
|
|
17
|
+
this.entries.set(name, { lastUsedMs: Date.now(), prefix });
|
|
18
|
+
}
|
|
19
|
+
/** Remove a resource from tracking. */
|
|
20
|
+
delete(name) {
|
|
21
|
+
this.entries.delete(name);
|
|
22
|
+
}
|
|
23
|
+
/** Get the entry for a resource, or undefined if not tracked. */
|
|
24
|
+
get(name) {
|
|
25
|
+
return this.entries.get(name);
|
|
26
|
+
}
|
|
27
|
+
/** Number of tracked resources. */
|
|
28
|
+
get size() {
|
|
29
|
+
return this.entries.size;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Iterate entries starting after `cursor`. Returns up to `budget` entries.
|
|
33
|
+
* When the end is reached, wraps around to the beginning.
|
|
34
|
+
* Returns the entries visited and whether a full cycle was completed.
|
|
35
|
+
*/
|
|
36
|
+
scan(cursor, budget) {
|
|
37
|
+
const maxToVisit = Math.min(budget, this.entries.size);
|
|
38
|
+
const visited = [];
|
|
39
|
+
let wrapped = false;
|
|
40
|
+
let pastCursor = cursor === undefined;
|
|
41
|
+
// First pass: from cursor to end
|
|
42
|
+
for (const [name, entry] of this.entries) {
|
|
43
|
+
if (visited.length >= maxToVisit) {
|
|
44
|
+
const nextCursor = visited.length > 0 ? visited[visited.length - 1][0] : cursor;
|
|
45
|
+
return { visited, nextCursor, wrapped: false };
|
|
46
|
+
}
|
|
47
|
+
if (!pastCursor) {
|
|
48
|
+
if (name === cursor) {
|
|
49
|
+
pastCursor = true;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
visited.push([name, entry]);
|
|
54
|
+
}
|
|
55
|
+
// Wrapped around — continue from start up to and including cursor
|
|
56
|
+
wrapped = true;
|
|
57
|
+
for (const [name, entry] of this.entries) {
|
|
58
|
+
if (visited.length >= maxToVisit)
|
|
59
|
+
break;
|
|
60
|
+
visited.push([name, entry]);
|
|
61
|
+
if (cursor !== undefined && name === cursor)
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
const nextCursor = visited.length > 0 ? visited[visited.length - 1][0] : undefined;
|
|
65
|
+
return { visited, nextCursor, wrapped };
|
|
66
|
+
}
|
|
67
|
+
/** Get all entries — primarily for listing/inspection. */
|
|
68
|
+
allEntries() {
|
|
69
|
+
return this.entries;
|
|
70
|
+
}
|
|
71
|
+
/** Return the next key after `name` in insertion order, or undefined if at end. */
|
|
72
|
+
nextAfter(name) {
|
|
73
|
+
let found = false;
|
|
74
|
+
for (const key of this.entries.keys()) {
|
|
75
|
+
if (found)
|
|
76
|
+
return key;
|
|
77
|
+
if (key === name)
|
|
78
|
+
found = true;
|
|
79
|
+
}
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
/** Clear all entries. */
|
|
83
|
+
clear() {
|
|
84
|
+
this.entries.clear();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=usageTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usageTracker.js","sourceRoot":"","sources":["../../src/tenant/usageTracker.ts"],"names":[],"mappings":"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"}
|