@alepha/bucket-azure 0.13.5 → 0.13.7

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.
@@ -1,12 +1,13 @@
1
1
  import { Readable } from "node:stream";
2
2
  import { BlobServiceClient, BlockBlobClient, ContainerClient, StoragePipelineOptions } from "@azure/storage-blob";
3
- import * as typebox0 from "typebox";
3
+ import * as typebox3 from "typebox";
4
4
  import { Static, StaticDecode as Static$1, StaticEncode, TAny, TArray, TArray as TArray$1, TBoolean, TInteger, TNumber, TObject, TObject as TObject$1, TOptional, TOptionalAdd, TRecord, TSchema, TSchema as TSchema$1, TString, TUnsafe } from "typebox";
5
5
  import { ReadableStream as ReadableStream$1 } from "node:stream/web";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { Validator } from "typebox/compile";
8
8
  import dayjsDuration from "dayjs/plugin/duration.js";
9
9
  import DayjsApi, { Dayjs, ManipulateType, PluginFunc } from "dayjs";
10
+ import "node:fs";
10
11
 
11
12
  //#region ../alepha/src/core/constants/KIND.d.ts
12
13
  /**
@@ -317,7 +318,7 @@ declare class JsonSchemaCodec extends SchemaCodec {
317
318
  //#endregion
318
319
  //#region ../alepha/src/core/providers/SchemaValidator.d.ts
319
320
  declare class SchemaValidator {
320
- protected cache: Map<TSchema, Validator<typebox0.TProperties, TSchema, unknown, unknown>>;
321
+ protected cache: Map<TSchema, Validator<typebox3.TProperties, TSchema, unknown, unknown>>;
321
322
  /**
322
323
  * Validate the value against the provided schema.
323
324
  *
@@ -421,7 +422,7 @@ declare class CodecManager {
421
422
  //#endregion
422
423
  //#region ../alepha/src/core/providers/EventManager.d.ts
423
424
  declare class EventManager {
424
- protected logFn?: () => LoggerInterface | undefined;
425
+ logFn?: () => LoggerInterface | undefined;
425
426
  /**
426
427
  * List of events that can be triggered. Powered by $hook().
427
428
  */
@@ -467,7 +468,7 @@ declare class StateManager<State$1 extends object = State> {
467
468
  protected readonly als: AlsProvider;
468
469
  protected readonly events: EventManager;
469
470
  protected readonly codec: JsonSchemaCodec;
470
- protected readonly atoms: Map<keyof State$1, Atom<TObject<typebox0.TProperties>, string>>;
471
+ protected readonly atoms: Map<keyof State$1, Atom<TObject<typebox3.TProperties>, string>>;
471
472
  protected store: Partial<State$1>;
472
473
  constructor(store?: Partial<State$1>);
473
474
  getAtoms(context?: boolean): Array<AtomWithValue>;
@@ -480,8 +481,8 @@ declare class StateManager<State$1 extends object = State> {
480
481
  /**
481
482
  * Set a value in the state
482
483
  */
483
- set<T extends TAtomObject>(target: Atom<T>, value: AtomStatic<T>): this;
484
- set<Key extends keyof State$1>(target: Key, value: State$1[Key] | undefined): this;
484
+ set<T extends TAtomObject>(target: Atom<T>, value: AtomStatic<T>, options?: SetStateOptions): this;
485
+ set<Key extends keyof State$1>(target: Key, value: State$1[Key] | undefined, options?: SetStateOptions): this;
485
486
  /**
486
487
  * Mutate a value in the state.
487
488
  */
@@ -498,7 +499,7 @@ declare class StateManager<State$1 extends object = State> {
498
499
  /**
499
500
  * Push a value to an array in the state
500
501
  */
501
- push<Key extends keyof OnlyArray<State$1>>(key: Key, value: NonNullable<State$1[Key]> extends Array<infer U> ? U : never): this;
502
+ push<Key extends keyof OnlyArray<State$1>>(key: Key, ...value: Array<NonNullable<State$1[Key]> extends Array<infer U> ? U : never>): this;
502
503
  /**
503
504
  * Clear all state
504
505
  */
@@ -509,6 +510,10 @@ declare class StateManager<State$1 extends object = State> {
509
510
  keys(): (keyof State$1)[];
510
511
  }
511
512
  type OnlyArray<T extends object> = { [K in keyof T]: NonNullable<T[K]> extends Array<any> ? K : never };
513
+ interface SetStateOptions {
514
+ skipContext?: boolean;
515
+ skipEvents?: boolean;
516
+ }
512
517
  //#endregion
513
518
  //#region ../alepha/src/core/Alepha.d.ts
514
519
  /**
@@ -665,12 +670,6 @@ declare class Alepha {
665
670
  * A promise that resolves when the App has started.
666
671
  */
667
672
  protected starting?: PromiseWithResolvers<this>;
668
- /**
669
- * Initial state of the container.
670
- *
671
- * > Used to initialize the StateManager.
672
- */
673
- protected init: Partial<State>;
674
673
  /**
675
674
  * During the instantiation process, we keep a list of pending instantiations.
676
675
  * > It allows us to detect circular dependencies.
@@ -710,21 +709,21 @@ declare class Alepha {
710
709
  *
711
710
  * Mocked for browser environments.
712
711
  */
713
- get context(): AlsProvider;
712
+ context: AlsProvider;
714
713
  /**
715
714
  * Event manager to handle lifecycle events and custom events.
716
715
  */
717
- get events(): EventManager;
716
+ events: EventManager;
718
717
  /**
719
718
  * State manager to store arbitrary values.
720
719
  */
721
- get store(): StateManager<State>;
720
+ store: StateManager<State>;
722
721
  /**
723
722
  * Codec manager for encoding and decoding data with different formats.
724
723
  *
725
724
  * Supports multiple codec formats (JSON, Protobuf, etc.) with a unified interface.
726
725
  */
727
- get codec(): CodecManager;
726
+ codec: CodecManager;
728
727
  /**
729
728
  * Get logger instance.
730
729
  */
@@ -733,7 +732,7 @@ declare class Alepha {
733
732
  * The environment variables for the App.
734
733
  */
735
734
  get env(): Readonly<Env>;
736
- constructor(init?: Partial<State>);
735
+ constructor(state?: Partial<State>);
737
736
  set<T extends TAtomObject>(target: Atom<T>, value: AtomStatic<T>): this;
738
737
  set<Key extends keyof State>(target: Key, value: State[Key] | undefined): this;
739
738
  /**
@@ -886,6 +885,15 @@ declare class Alepha {
886
885
  * @return The schema object with environment variables applied.
887
886
  */
888
887
  parseEnv<T extends TObject>(schema: T): Static<T>;
888
+ /**
889
+ * Get all environment variable schemas and their parsed values.
890
+ *
891
+ * This is useful for DevTools to display all expected environment variables.
892
+ */
893
+ getEnvSchemas(): Array<{
894
+ schema: TSchema$1;
895
+ values: Record<string, any>;
896
+ }>;
889
897
  /**
890
898
  * Dump the current dependency graph of the App.
891
899
  *
@@ -1269,7 +1277,7 @@ declare const envSchema$1: TObject$1<{
1269
1277
  /**
1270
1278
  * Built-in log formats.
1271
1279
  * - "json" - JSON format, useful for structured logging and log aggregation. {@link JsonFormatterProvider}
1272
- * - "pretty" - Simple text format, human-readable, with colors. {@link SimpleFormatterProvider}
1280
+ * - "pretty" - Simple text format, human-readable, with colors. {@link PrettyFormatterProvider}
1273
1281
  * - "raw" - Raw format, no formatting, just the message. {@link RawFormatterProvider}
1274
1282
  */
1275
1283
  LOG_FORMAT: TOptional<TUnsafe<"json" | "pretty" | "raw">>;
@@ -1996,4 +2004,5 @@ declare class AzureFileStorageProvider implements FileStorageProvider {
1996
2004
  */
1997
2005
  declare const AlephaBucketAzure: Service<Module>;
1998
2006
  //#endregion
1999
- export { AlephaBucketAzure, AzureFileStorageProvider };
2007
+ export { AlephaBucketAzure, AzureFileStorageProvider };
2008
+ //# sourceMappingURL=index.d.ts.map
@@ -121,4 +121,5 @@ const AlephaBucketAzure = $module({
121
121
  });
122
122
 
123
123
  //#endregion
124
- export { AlephaBucketAzure, AzureFileStorageProvider };
124
+ export { AlephaBucketAzure, AzureFileStorageProvider };
125
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/providers/AzureFileStorageProvider.ts","../src/index.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { Readable } from \"node:stream\";\nimport {\n BlobServiceClient,\n type BlockBlobClient,\n type ContainerClient,\n type StoragePipelineOptions,\n} from \"@azure/storage-blob\";\nimport {\n $env,\n $hook,\n $inject,\n Alepha,\n type FileLike,\n type Static,\n t,\n} from \"alepha\";\nimport {\n $bucket,\n FileNotFoundError,\n type FileStorageProvider,\n} from \"alepha/bucket\";\nimport { DateTimeProvider } from \"alepha/datetime\";\nimport { FileSystemProvider } from \"alepha/file\";\nimport { $logger } from \"alepha/logger\";\n\nconst envSchema = t.object({\n AZ_STORAGE_CONNECTION_STRING: t.string(),\n});\n\ndeclare module \"alepha\" {\n interface Env extends Partial<Static<typeof envSchema>> {}\n}\n\n/**\n * Azure Blog Storage implementation of File Storage Provider.\n */\nexport class AzureFileStorageProvider implements FileStorageProvider {\n protected readonly log = $logger();\n protected readonly env = $env(envSchema);\n protected readonly alepha = $inject(Alepha);\n protected readonly time = $inject(DateTimeProvider);\n protected readonly fileSystem = $inject(FileSystemProvider);\n protected readonly containers: Record<string, ContainerClient> = {};\n protected readonly blobServiceClient: BlobServiceClient;\n\n public readonly options: StoragePipelineOptions = {};\n\n constructor() {\n this.blobServiceClient = BlobServiceClient.fromConnectionString(\n this.env.AZ_STORAGE_CONNECTION_STRING,\n this.options,\n );\n }\n\n protected readonly onStart = $hook({\n on: \"start\",\n handler: async () => {\n for (const bucket of this.alepha.primitives($bucket)) {\n if (bucket.provider !== this) {\n continue;\n }\n\n const containerName = this.convertName(bucket.name);\n\n this.log.debug(`Prepare container '${containerName}' ...`);\n\n if (!this.containers[containerName]) {\n this.containers[containerName] =\n await this.createContainerClient(containerName);\n }\n\n this.log.info(`Container '${bucket.name}' OK`);\n }\n },\n });\n\n public convertName(name: string): string {\n // Azure Blob Storage does not allow uppercase letters in container names\n return name.replaceAll(\"/\", \"-\").toLowerCase();\n }\n\n public async upload(\n bucketName: string,\n file: FileLike,\n fileId?: string,\n ): Promise<string> {\n fileId ??= this.createId();\n\n this.log.trace(\n `Uploading file '${file.name}' to bucket '${bucketName}' with id '${fileId}'...`,\n );\n\n const block = this.getBlock(bucketName, fileId);\n\n const metadata = {\n name: file.name,\n type: file.type,\n };\n\n if (file.filepath) {\n await block.uploadFile(file.filepath, {\n metadata,\n blobHTTPHeaders: {\n blobContentType: file.type,\n },\n });\n } else if (file.size > 0) {\n await block.uploadData(await file.arrayBuffer(), {\n metadata,\n blobHTTPHeaders: {\n blobContentType: file.type,\n },\n });\n } else {\n await block.uploadStream(\n Readable.from(file.stream()),\n file.size || undefined,\n 5,\n {\n metadata,\n blobHTTPHeaders: {\n blobContentType: file.type,\n },\n },\n );\n }\n\n return fileId;\n }\n\n public async download(bucketName: string, fileId: string): Promise<FileLike> {\n this.log.trace(\n `Downloading file '${fileId}' from bucket '${bucketName}'...`,\n );\n const block = this.getBlock(bucketName, fileId);\n\n const blob = await block.download().catch((error) => {\n if (error instanceof Error) {\n throw new FileNotFoundError(\"Error downloading file\", { cause: error });\n }\n\n throw error;\n });\n\n if (!blob.readableStreamBody) {\n throw new FileNotFoundError(\"File not found - empty stream body\");\n }\n\n return this.fileSystem.createFile({\n stream: blob.readableStreamBody,\n ...blob.metadata,\n size: blob.contentLength,\n });\n }\n\n public async exists(bucketName: string, fileId: string): Promise<boolean> {\n this.log.trace(\n `Checking existence of file '${fileId}' in bucket '${bucketName}'...`,\n );\n return await this.getBlock(bucketName, fileId).exists();\n }\n\n public async delete(bucketName: string, fileId: string): Promise<void> {\n this.log.trace(`Deleting file '${fileId}' from bucket '${bucketName}'...`);\n try {\n await this.getBlock(bucketName, fileId).delete();\n } catch (error) {\n if (error instanceof Error) {\n throw new FileNotFoundError(\"Error deleting file\", { cause: error });\n }\n throw error;\n }\n }\n\n public getBlock(container: string, fileId: string): BlockBlobClient {\n const containerName = this.convertName(container);\n\n if (!this.containers[containerName]) {\n throw new FileNotFoundError(\n `File '${fileId}' not found - container '${container}' does not exists`,\n );\n }\n\n return this.containers[containerName].getBlockBlobClient(fileId);\n }\n\n protected async createContainerClient(\n name: string,\n ): Promise<ContainerClient> {\n const container = this.blobServiceClient.getContainerClient(name);\n\n await this.time.deadline(\n (abortSignal) => container.createIfNotExists({ abortSignal }),\n [5, \"seconds\"],\n );\n\n return container;\n }\n\n protected createId(): string {\n return randomUUID();\n }\n}\n","import { $module } from \"alepha\";\nimport { AlephaBucket, FileStorageProvider } from \"alepha/bucket\";\nimport { AzureFileStorageProvider } from \"./providers/AzureFileStorageProvider.ts\";\n\nexport * from \"./providers/AzureFileStorageProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Plugin for Alepha Bucket that provides Azure Blob Storage capabilities.\n *\n * @see {@link AzureFileStorageProvider}\n * @module alepha.bucket.azure\n */\nexport const AlephaBucketAzure = $module({\n name: \"alepha.bucket.azure\",\n services: [AzureFileStorageProvider],\n register: (alepha) =>\n alepha\n .with({\n optional: true,\n provide: FileStorageProvider,\n use: AzureFileStorageProvider,\n })\n .with(AlephaBucket),\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "storage-blob"
11
11
  ],
12
12
  "author": "Nicolas Foures",
13
- "version": "0.13.5",
13
+ "version": "0.13.7",
14
14
  "type": "module",
15
15
  "engines": {
16
16
  "node": ">=22.0.0"
@@ -26,12 +26,12 @@
26
26
  "@azure/storage-blob": "^12.29.1"
27
27
  },
28
28
  "devDependencies": {
29
- "alepha": "0.13.5",
30
- "tsdown": "^0.17.0",
29
+ "alepha": "0.13.7",
30
+ "tsdown": "^0.17.2",
31
31
  "vitest": "^4.0.15"
32
32
  },
33
33
  "peerDependencies": {
34
- "alepha": "0.13.5"
34
+ "alepha": "0.13.7"
35
35
  },
36
36
  "scripts": {
37
37
  "lint": "alepha lint",