@soulbatical/tetra-core 0.1.46 → 0.1.47

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.
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Storage Upload Service — server-side upload to Supabase Storage
3
+ *
4
+ * Centralizes all file uploads (images, PDFs, videos, any file type).
5
+ * Returns proxy URLs, never Supabase URLs.
6
+ *
7
+ * Three upload modes:
8
+ * 1. uploadFile() — single file upload, returns proxy URL
9
+ * 2. uploadMultiSize() — image upload with resize to multiple sizes (sharp)
10
+ * 3. uploadPrivate() — private bucket upload, returns signed URL
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * import { StorageUploadService } from '@soulbatical/tetra-core';
15
+ *
16
+ * const storage = new StorageUploadService(supabase, {
17
+ * allowedBuckets: ['images', 'pdf-books', 'community-media'],
18
+ * });
19
+ *
20
+ * // Public file
21
+ * const result = await storage.uploadFile('images', buffer, {
22
+ * path: 'ai-generated/org123/photo.jpg',
23
+ * contentType: 'image/jpeg',
24
+ * });
25
+ * // result.proxyUrl → "/api/public/storage/images/ai-generated/org123/photo.jpg"
26
+ *
27
+ * // Multi-size image
28
+ * const results = await storage.uploadMultiSize('images', buffer, {
29
+ * prefix: 'ai-generated/org123',
30
+ * baseFilename: 'photo.jpg',
31
+ * });
32
+ * // results[0].proxyUrl → ".../photo-thumb.jpg"
33
+ *
34
+ * // Private file (signed URL)
35
+ * const result = await storage.uploadPrivate('pdf-books', buffer, {
36
+ * path: 'books/user123/book.pdf',
37
+ * contentType: 'application/pdf',
38
+ * expiresIn: 3600 * 24 * 30, // 30 days
39
+ * });
40
+ * // result.signedUrl → "https://...supabase.co/storage/v1/sign/..."
41
+ * ```
42
+ */
43
+ import type { SupabaseClient } from '@supabase/supabase-js';
44
+ import type { StorageConfig, UploadResult, ImageSize } from './types.js';
45
+ export interface FileUploadOptions {
46
+ /** Storage path within bucket (e.g. "ai-generated/org123/photo.jpg") */
47
+ path: string;
48
+ /** MIME type (e.g. "image/jpeg", "application/pdf") */
49
+ contentType: string;
50
+ /** Overwrite if exists (default: false) */
51
+ upsert?: boolean;
52
+ }
53
+ export interface MultiSizeUploadOptions {
54
+ /** Folder prefix (e.g. "ai-generated/org123") */
55
+ prefix: string;
56
+ /** Base filename (e.g. "photo.jpg") — sizes will be "{base}-{size}.{ext}" */
57
+ baseFilename: string;
58
+ /** Custom sizes (defaults to STANDARD_IMAGE_SIZES) */
59
+ sizes?: ImageSize[];
60
+ /** Image format (defaults to 'jpeg') */
61
+ format?: 'jpeg' | 'png' | 'webp';
62
+ }
63
+ export interface PrivateUploadOptions extends FileUploadOptions {
64
+ /** Signed URL expiry in seconds (default: 30 days) */
65
+ expiresIn?: number;
66
+ }
67
+ export interface PrivateUploadResult {
68
+ bucket: string;
69
+ path: string;
70
+ signedUrl: string;
71
+ contentType: string;
72
+ size: number;
73
+ }
74
+ export interface MultiSizeUploadResult {
75
+ /** All uploaded sizes with their proxy URLs */
76
+ sizes: Array<UploadResult & {
77
+ sizeName: string;
78
+ }>;
79
+ /** Base filename for DB storage */
80
+ baseFilename: string;
81
+ /** Storage prefix for DB storage */
82
+ storagePrefix: string;
83
+ }
84
+ export declare class StorageUploadService {
85
+ private readonly config;
86
+ private readonly supabase;
87
+ constructor(supabase: SupabaseClient, config: Partial<StorageConfig> & {
88
+ allowedBuckets: string[];
89
+ });
90
+ private validateBucket;
91
+ /**
92
+ * Upload a single file to a public bucket.
93
+ * Returns a proxy URL — never a Supabase URL.
94
+ */
95
+ uploadFile(bucket: string, buffer: Buffer, options: FileUploadOptions): Promise<UploadResult>;
96
+ /**
97
+ * Upload an image in multiple sizes (thumb, medium, large, original).
98
+ * Requires sharp as a peer dependency.
99
+ * Returns proxy URLs for all sizes.
100
+ */
101
+ uploadMultiSize(bucket: string, buffer: Buffer, options: MultiSizeUploadOptions): Promise<MultiSizeUploadResult>;
102
+ /**
103
+ * Upload a file to a private bucket.
104
+ * Returns a signed URL (for PDFs, protected documents, etc.)
105
+ */
106
+ uploadPrivate(bucket: string, buffer: Buffer, options: PrivateUploadOptions): Promise<PrivateUploadResult>;
107
+ /**
108
+ * Delete a file from storage.
109
+ */
110
+ deleteFile(bucket: string, path: string): Promise<void>;
111
+ /**
112
+ * Ensure a bucket exists (create if missing).
113
+ * Call once at startup if needed.
114
+ */
115
+ ensureBucket(bucket: string, options?: {
116
+ public?: boolean;
117
+ fileSizeLimit?: number;
118
+ allowedMimeTypes?: string[];
119
+ }): Promise<void>;
120
+ /**
121
+ * Build a proxy URL for a given bucket and path.
122
+ * Use this when you already have the path and just need the URL.
123
+ */
124
+ static buildProxyUrl(bucket: string, path: string): string;
125
+ }
126
+ //# sourceMappingURL=StorageUploadService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorageUploadService.d.ts","sourceRoot":"","sources":["../../../src/shared/storage/StorageUploadService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAwB,MAAM,YAAY,CAAC;AAK/F,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;IACpB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,KAAK,EAAE,KAAK,CAAC,YAAY,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,aAAa,EAAE,MAAM,CAAC;CACvB;AAOD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;gBAE9B,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG;QAAE,cAAc,EAAE,MAAM,EAAE,CAAA;KAAE;IAWnG,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAiCnG;;;;OAIG;IACG,eAAe,CACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC;IAqCjC;;;OAGG;IACG,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC;IAyC/B;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe7D;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACtF,OAAO,CAAC,IAAI,CAAC;IAmBhB;;;OAGG;IACH,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;CAG3D"}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Storage Upload Service — server-side upload to Supabase Storage
3
+ *
4
+ * Centralizes all file uploads (images, PDFs, videos, any file type).
5
+ * Returns proxy URLs, never Supabase URLs.
6
+ *
7
+ * Three upload modes:
8
+ * 1. uploadFile() — single file upload, returns proxy URL
9
+ * 2. uploadMultiSize() — image upload with resize to multiple sizes (sharp)
10
+ * 3. uploadPrivate() — private bucket upload, returns signed URL
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * import { StorageUploadService } from '@soulbatical/tetra-core';
15
+ *
16
+ * const storage = new StorageUploadService(supabase, {
17
+ * allowedBuckets: ['images', 'pdf-books', 'community-media'],
18
+ * });
19
+ *
20
+ * // Public file
21
+ * const result = await storage.uploadFile('images', buffer, {
22
+ * path: 'ai-generated/org123/photo.jpg',
23
+ * contentType: 'image/jpeg',
24
+ * });
25
+ * // result.proxyUrl → "/api/public/storage/images/ai-generated/org123/photo.jpg"
26
+ *
27
+ * // Multi-size image
28
+ * const results = await storage.uploadMultiSize('images', buffer, {
29
+ * prefix: 'ai-generated/org123',
30
+ * baseFilename: 'photo.jpg',
31
+ * });
32
+ * // results[0].proxyUrl → ".../photo-thumb.jpg"
33
+ *
34
+ * // Private file (signed URL)
35
+ * const result = await storage.uploadPrivate('pdf-books', buffer, {
36
+ * path: 'books/user123/book.pdf',
37
+ * contentType: 'application/pdf',
38
+ * expiresIn: 3600 * 24 * 30, // 30 days
39
+ * });
40
+ * // result.signedUrl → "https://...supabase.co/storage/v1/sign/..."
41
+ * ```
42
+ */
43
+ import { createLogger } from '../../utils/logger.js';
44
+ const logger = createLogger('storage:upload');
45
+ function buildProxyUrl(bucket, path) {
46
+ const clean = path.startsWith('/') ? path.substring(1) : path;
47
+ return `/api/public/storage/${bucket}/${clean}`;
48
+ }
49
+ export class StorageUploadService {
50
+ config;
51
+ supabase;
52
+ constructor(supabase, config) {
53
+ this.supabase = supabase;
54
+ this.config = {
55
+ allowedBuckets: config.allowedBuckets,
56
+ supabaseUrl: config.supabaseUrl || process.env.SUPABASE_URL,
57
+ supabaseServiceKey: config.supabaseServiceKey || process.env.SUPABASE_SERVICE_ROLE_KEY,
58
+ maxUploadBytes: config.maxUploadBytes ?? 50 * 1024 * 1024,
59
+ cacheMaxAge: config.cacheMaxAge ?? 3600,
60
+ };
61
+ }
62
+ validateBucket(bucket) {
63
+ if (!this.config.allowedBuckets.includes(bucket)) {
64
+ throw new Error(`Bucket "${bucket}" is not in the allowed list: [${this.config.allowedBuckets.join(', ')}]`);
65
+ }
66
+ }
67
+ /**
68
+ * Upload a single file to a public bucket.
69
+ * Returns a proxy URL — never a Supabase URL.
70
+ */
71
+ async uploadFile(bucket, buffer, options) {
72
+ this.validateBucket(bucket);
73
+ if (this.config.maxUploadBytes && buffer.length > this.config.maxUploadBytes) {
74
+ throw new Error(`File size ${buffer.length} exceeds limit ${this.config.maxUploadBytes}`);
75
+ }
76
+ logger.debug({ bucket, path: options.path, size: buffer.length }, 'Uploading file');
77
+ const { data, error } = await this.supabase.storage
78
+ .from(bucket)
79
+ .upload(options.path, buffer, {
80
+ contentType: options.contentType,
81
+ upsert: options.upsert ?? false,
82
+ });
83
+ if (error) {
84
+ logger.error({ error, bucket, path: options.path }, 'Upload failed');
85
+ throw new Error(`Upload failed: ${error.message}`);
86
+ }
87
+ const result = {
88
+ bucket,
89
+ path: data.path,
90
+ proxyUrl: buildProxyUrl(bucket, data.path),
91
+ contentType: options.contentType,
92
+ size: buffer.length,
93
+ };
94
+ logger.info({ bucket, path: data.path, size: buffer.length }, 'File uploaded');
95
+ return result;
96
+ }
97
+ /**
98
+ * Upload an image in multiple sizes (thumb, medium, large, original).
99
+ * Requires sharp as a peer dependency.
100
+ * Returns proxy URLs for all sizes.
101
+ */
102
+ async uploadMultiSize(bucket, buffer, options) {
103
+ this.validateBucket(bucket);
104
+ // Dynamic import — sharp is optional peer dep
105
+ const { ImageProcessingService, STANDARD_IMAGE_SIZES } = await import('./ImageProcessingService.js');
106
+ const sizes = options.sizes || STANDARD_IMAGE_SIZES;
107
+ const processed = await ImageProcessingService.generateMultipleSizes(buffer, {
108
+ sizes,
109
+ format: options.format,
110
+ });
111
+ const ext = options.baseFilename.split('.').pop() || 'jpg';
112
+ const baseWithoutExt = options.baseFilename.replace(/\.[^.]+$/, '');
113
+ const uploadResults = await Promise.all(processed.map(async (item) => {
114
+ const filename = `${baseWithoutExt}-${item.size}.${ext}`;
115
+ const path = `${options.prefix}/${filename}`;
116
+ const result = await this.uploadFile(bucket, item.buffer, {
117
+ path,
118
+ contentType: `image/${options.format || 'jpeg'}`,
119
+ upsert: true,
120
+ });
121
+ return { ...result, sizeName: item.size };
122
+ }));
123
+ return {
124
+ sizes: uploadResults,
125
+ baseFilename: options.baseFilename,
126
+ storagePrefix: options.prefix,
127
+ };
128
+ }
129
+ /**
130
+ * Upload a file to a private bucket.
131
+ * Returns a signed URL (for PDFs, protected documents, etc.)
132
+ */
133
+ async uploadPrivate(bucket, buffer, options) {
134
+ this.validateBucket(bucket);
135
+ if (this.config.maxUploadBytes && buffer.length > this.config.maxUploadBytes) {
136
+ throw new Error(`File size ${buffer.length} exceeds limit ${this.config.maxUploadBytes}`);
137
+ }
138
+ logger.debug({ bucket, path: options.path, size: buffer.length }, 'Uploading private file');
139
+ const { data, error } = await this.supabase.storage
140
+ .from(bucket)
141
+ .upload(options.path, buffer, {
142
+ contentType: options.contentType,
143
+ upsert: options.upsert ?? false,
144
+ });
145
+ if (error) {
146
+ logger.error({ error, bucket, path: options.path }, 'Private upload failed');
147
+ throw new Error(`Upload failed: ${error.message}`);
148
+ }
149
+ const expiresIn = options.expiresIn ?? 3600 * 24 * 30; // 30 days default
150
+ const { data: signedData, error: signError } = await this.supabase.storage
151
+ .from(bucket)
152
+ .createSignedUrl(data.path, expiresIn);
153
+ if (signError || !signedData?.signedUrl) {
154
+ throw new Error(`Failed to create signed URL: ${signError?.message || 'No URL returned'}`);
155
+ }
156
+ logger.info({ bucket, path: data.path, size: buffer.length }, 'Private file uploaded');
157
+ return {
158
+ bucket,
159
+ path: data.path,
160
+ signedUrl: signedData.signedUrl,
161
+ contentType: options.contentType,
162
+ size: buffer.length,
163
+ };
164
+ }
165
+ /**
166
+ * Delete a file from storage.
167
+ */
168
+ async deleteFile(bucket, path) {
169
+ this.validateBucket(bucket);
170
+ const { error } = await this.supabase.storage
171
+ .from(bucket)
172
+ .remove([path]);
173
+ if (error) {
174
+ logger.error({ error, bucket, path }, 'Delete failed');
175
+ throw new Error(`Delete failed: ${error.message}`);
176
+ }
177
+ logger.info({ bucket, path }, 'File deleted');
178
+ }
179
+ /**
180
+ * Ensure a bucket exists (create if missing).
181
+ * Call once at startup if needed.
182
+ */
183
+ async ensureBucket(bucket, options = {}) {
184
+ const { data: buckets } = await this.supabase.storage.listBuckets();
185
+ const exists = buckets?.some(b => b.name === bucket);
186
+ if (!exists) {
187
+ const { error } = await this.supabase.storage.createBucket(bucket, {
188
+ public: options.public ?? true,
189
+ fileSizeLimit: options.fileSizeLimit,
190
+ allowedMimeTypes: options.allowedMimeTypes,
191
+ });
192
+ if (error) {
193
+ throw new Error(`Failed to create bucket "${bucket}": ${error.message}`);
194
+ }
195
+ logger.info({ bucket }, 'Bucket created');
196
+ }
197
+ }
198
+ /**
199
+ * Build a proxy URL for a given bucket and path.
200
+ * Use this when you already have the path and just need the URL.
201
+ */
202
+ static buildProxyUrl(bucket, path) {
203
+ return buildProxyUrl(bucket, path);
204
+ }
205
+ }
206
+ //# sourceMappingURL=StorageUploadService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StorageUploadService.js","sourceRoot":"","sources":["../../../src/shared/storage/StorageUploadService.ts"],"names":[],"mappings":"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"}
@@ -21,5 +21,7 @@
21
21
  export { addStorageProxyRoutes, addStorageUploadRoutes } from './routes.js';
22
22
  export { StorageProxyService } from './StorageProxyService.js';
23
23
  export { ImageProcessingService, STANDARD_IMAGE_SIZES } from './ImageProcessingService.js';
24
+ export { StorageUploadService } from './StorageUploadService.js';
24
25
  export type { StorageConfig, StorageProxyOptions, StorageUploadOptions, UploadResult, ImageSize, ProcessedImageResult, ImageProcessingOptions, } from './types.js';
26
+ export type { FileUploadOptions, MultiSizeUploadOptions, PrivateUploadOptions, PrivateUploadResult, MultiSizeUploadResult, } from './StorageUploadService.js';
25
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,YAAY,EACV,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shared/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EACV,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,SAAS,EACT,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC"}
@@ -21,4 +21,5 @@
21
21
  export { addStorageProxyRoutes, addStorageUploadRoutes } from './routes.js';
22
22
  export { StorageProxyService } from './StorageProxyService.js';
23
23
  export { ImageProcessingService, STANDARD_IMAGE_SIZES } from './ImageProcessingService.js';
24
+ export { StorageUploadService } from './StorageUploadService.js';
24
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/shared/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soulbatical/tetra-core",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "publishConfig": {
5
5
  "access": "restricted"
6
6
  },