@progressive-development/pd-spa-helper 0.1.159 → 0.1.160

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent pd-spa-helper following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "pd-spa-helper",
6
- "version": "0.1.159",
6
+ "version": "0.1.160",
7
7
  "main": "dist/src/index.js",
8
8
  "module": "dist/src/index.js",
9
9
  "exports": {
package/src/index.ts CHANGED
@@ -31,7 +31,8 @@ export {
31
31
  loginImpl,
32
32
  logoutImpl,
33
33
  isAuthenticatedImpl,
34
- callFunctionImpl
34
+ callFunctionImpl,
35
+ uploadFile
35
36
  } from './service-provider/service-provider-impl.js'
36
37
 
37
38
  export { pdStore } from './store/mini-rx.store.js';
@@ -0,0 +1,82 @@
1
+ import { FirebaseApp } from 'firebase/app';
2
+ import { FirebaseStorage, StorageReference, UploadResult, getStorage, ref, uploadString } from "firebase/storage";
3
+
4
+ import { FileStorageConfig, UploadFile } from '../service-provider-model.js';
5
+
6
+ const DEFAULT_STORAGE = "default_storage";
7
+
8
+ const storageMap:Map<string, {
9
+ storage: FirebaseStorage,
10
+ references?: {
11
+ key: string,
12
+ storageRef: StorageReference
13
+ }[],
14
+ }> = new Map();
15
+
16
+ /**
17
+ * During start/load application, initialize functions.
18
+ *
19
+ * @param {*} app - initialized app.
20
+ */
21
+ export const initFirestorage = (app: FirebaseApp, defaultStorage?: string, storageConfig?: FileStorageConfig) => {
22
+ try {
23
+
24
+ // add default storage
25
+ if (defaultStorage) {
26
+ storageMap.set(DEFAULT_STORAGE, {
27
+ storage: getStorage(app)
28
+ });
29
+ }
30
+
31
+ // add specific storages
32
+ storageConfig?.storage.forEach(storeConfig => {
33
+
34
+ const storage = getStorage(app, storeConfig.name);
35
+ const storageRootRef = ref(storage);
36
+
37
+ storageMap.set(storeConfig.name, {
38
+ storage,
39
+ references: [
40
+ {
41
+ key: "ROOT",
42
+ storageRef: storageRootRef
43
+ },
44
+ ...storeConfig.references.map(refConfigString => ({
45
+ key: refConfigString,
46
+ storageRef: ref(storageRootRef, refConfigString)
47
+ }))
48
+ ]
49
+ });
50
+ });
51
+
52
+ } catch (error) {
53
+ console.error(error);
54
+ }
55
+ };
56
+
57
+ export const uploadFirestorageFile = (file: UploadFile):Promise<UploadResult> => {
58
+
59
+ if (!storageMap || storageMap.size === 0) {
60
+ throw new Error("No storage is configured");
61
+ }
62
+
63
+ // get storage
64
+ const {storageName, referenceKey, subFolderName, fileName} = file;
65
+ const storageConf = storageMap.get(storageName || DEFAULT_STORAGE);
66
+ if (!storageConf ) {
67
+ throw new Error(`Invalid storage name: ${storageName || DEFAULT_STORAGE}`);
68
+ }
69
+ if (!storageConf.references || storageConf.references.length === 0) {
70
+ throw new Error(`No references configured for storage: ${storageName || DEFAULT_STORAGE}`);
71
+ }
72
+
73
+ // get reference to path
74
+ const uploadRefConf = referenceKey ? (storageConf.references.filter(filterRef => filterRef.key === referenceKey)[0]) : storageConf.references[0];
75
+ if (!uploadRefConf || !uploadRefConf.storageRef) {
76
+ throw new Error(`No valid reference for key: ${referenceKey}`);
77
+ }
78
+
79
+ // create file reference and upload
80
+ const fileRef = ref(uploadRefConf.storageRef, subFolderName ? `${subFolderName}/${fileName}` : fileName);
81
+ return uploadString(fileRef, file.base64DataURL, 'data_url');
82
+ };
@@ -0,0 +1,124 @@
1
+ import { FileStorageConfig, UploadFile } from '../service-provider-model.js';
2
+
3
+
4
+ const DEFAULT_STORAGE = "default_storage";
5
+
6
+
7
+ // Download file in mock implementation
8
+ const downloadFile = (buffer: ArrayBuffer) => {
9
+ const data: Blob = new Blob([buffer], {
10
+ type: 'image/png'
11
+ });
12
+ const url= window.URL.createObjectURL(data);
13
+ window.open(url);
14
+ }
15
+
16
+ const base64ToArrayBuffer = (base64:string) => {
17
+ const binaryString = atob(base64);
18
+ const bytes = new Uint8Array(binaryString.length);
19
+ for (let i = 0; i < binaryString.length; i+=1) {
20
+ bytes[i] = binaryString.charCodeAt(i);
21
+ }
22
+ return bytes.buffer;
23
+ }
24
+
25
+
26
+ class MockStorage {
27
+
28
+ private _name: string;
29
+
30
+ constructor(storageName: string) {
31
+ this._name = storageName;
32
+ }
33
+
34
+ // eslint-disable-next-line class-methods-use-this
35
+ uploadFile(filePath: string, file: UploadFile): Promise<any> {
36
+ downloadFile(
37
+ base64ToArrayBuffer(file.base64DataURL)
38
+ );
39
+ return Promise.resolve({
40
+ fullPath: filePath
41
+ });
42
+ }
43
+
44
+ }
45
+
46
+ const storageMap:Map<string, {
47
+ storage: MockStorage,
48
+ references?: {
49
+ key: string,
50
+ storageRef: string
51
+ }[],
52
+ }> = new Map();
53
+
54
+ /**
55
+ * During start/load application, initialize functions.
56
+ *
57
+ * @param {*} app - initialized app.
58
+ */
59
+ export const initStorageMock = (defaultStorage?: string, storageConfig?: FileStorageConfig) => {
60
+ console.log("Init mock Storage");
61
+ try {
62
+
63
+ // add default storage
64
+ if (defaultStorage) {
65
+ storageMap.set(DEFAULT_STORAGE, {
66
+ storage: new MockStorage(DEFAULT_STORAGE)
67
+ });
68
+ }
69
+
70
+ // add specific storages
71
+ storageConfig?.storage.forEach(storeConfig => {
72
+
73
+ const storage = new MockStorage(storeConfig.name);
74
+ const storageRootRef = "/";
75
+
76
+ storageMap.set(storeConfig.name, {
77
+ storage,
78
+ references: [
79
+ {
80
+ key: "ROOT",
81
+ storageRef: storageRootRef
82
+ },
83
+ ...storeConfig.references.map(refConfigString => ({
84
+ key: refConfigString,
85
+ storageRef: `${storageRootRef}/${refConfigString}`
86
+ }))
87
+ ]
88
+ });
89
+ });
90
+
91
+ } catch (error) {
92
+ console.error(error);
93
+ }
94
+ };
95
+
96
+
97
+ export const uploadStorageFileMock = (file: UploadFile):Promise<any> => {
98
+
99
+ if (!storageMap || storageMap.size === 0) {
100
+ throw new Error("No storage is configured");
101
+ }
102
+
103
+ // get storage
104
+ const {storageName, referenceKey, subFolderName, fileName} = file;
105
+ const storageConf = storageMap.get(storageName || DEFAULT_STORAGE);
106
+ if (!storageConf ) {
107
+ throw new Error(`Invalid storage name: ${storageName || DEFAULT_STORAGE}`);
108
+ }
109
+ if (!storageConf.references || storageConf.references.length === 0) {
110
+ throw new Error(`No references configured for storage: ${storageName || DEFAULT_STORAGE}`);
111
+ }
112
+
113
+ // get reference to path
114
+ const uploadRefConf = referenceKey ? (storageConf.references.filter(filterRef => filterRef.key === referenceKey)[0]) : storageConf.references[0];
115
+ if (!uploadRefConf || !uploadRefConf.storageRef) {
116
+ throw new Error(`No valid reference for key: ${referenceKey}`);
117
+ }
118
+
119
+ // create file reference and upload
120
+ const fileRef = `${uploadRefConf.storageRef}/${subFolderName ? `${subFolderName}/${fileName}` : fileName}`;
121
+ return storageConf.storage.uploadFile(fileRef, file);
122
+ };
123
+
124
+
@@ -1,12 +1,14 @@
1
- import { FirebaseApp, initializeApp } from "firebase/app";
1
+ import { FirebaseApp, FirebaseOptions, initializeApp } from "firebase/app";
2
2
 
3
3
  import { authStateChanged, isAuthenticated, login, logout } from "./firebase/auth.js";
4
4
  import { authStateChangedMock, isAuthenticatedMock, loginMock, logoutMock } from "./mock/auth.js";
5
- import { AppConfiguration, FunctionDefinition, FunctionResult, FunctionsConfig, ServiceProviderConfiguration } from "./service-provider-model.js";
5
+ import { AppConfiguration, FileStorageConfig, FunctionDefinition, FunctionResult, FunctionsConfig, ServiceProviderConfiguration, UploadFile } from "./service-provider-model.js";
6
6
  import { callFunction, initFunctions } from "./firebase/functions-client.js";
7
7
  import { initFirestore } from "./firebase/firestore-client.js";
8
8
  import { callFunctionMock, initMockResponse } from "./mock/function-client.js";
9
9
  import { ServiceCallController } from "../service-call-controller2.js";
10
+ import { initFirestorage, uploadFirestorageFile } from "./firebase/firestorage-client.js";
11
+ import { initStorageMock, uploadStorageFileMock } from "./mock/storage-client.js";
10
12
 
11
13
  let provider: ServiceProviderConfiguration | undefined;
12
14
  let controller: ServiceCallController;
@@ -27,22 +29,30 @@ export const initController = (controllerParam: ServiceCallController) => {
27
29
  controller = controllerParam
28
30
  }
29
31
 
30
- const initFirebaseApplicationServices = (firebaseApp: FirebaseApp, functionsConfig: FunctionsConfig) => {
32
+ const initFirebaseApplicationServices = (
33
+ firebaseApp: FirebaseApp,
34
+ functionsConfig: FunctionsConfig,
35
+ firebaseConfig: FirebaseOptions,
36
+ storageConfig?: FileStorageConfig,
37
+ ) => {
31
38
  // do something with the app, init db, firestore and functions
32
39
  initFunctions(firebaseApp, functionsConfig);
33
- initFirestore(firebaseApp);
40
+ initFirestore(firebaseApp);
41
+ initFirestorage(firebaseApp, firebaseConfig.storageBucket, storageConfig);
42
+
34
43
  }
35
44
 
36
45
  export const initAppImpl = (config: AppConfiguration) => {
37
46
 
38
47
  if (provider === "firebase" && config.firebaseConfig) {
39
48
  const app:FirebaseApp = initializeApp(config.firebaseConfig);
40
- if (config.functionsConfig) {
49
+ if (config.functionsConfig) { // TODO: invalid if only storage config exists
41
50
  // init application services (functions, store)
42
- initFirebaseApplicationServices(app, config.functionsConfig);
51
+ initFirebaseApplicationServices(app, config.functionsConfig, config.firebaseConfig, config.storageConfig);
43
52
  }
44
53
  } else if (provider === "mock") {
45
54
  initMockResponse(config.mock);
55
+ initStorageMock("default", config.storageConfig);
46
56
  } else {
47
57
  throwUndefinedProviderError();
48
58
  }
@@ -131,3 +141,16 @@ export const logoutImpl = () => {
131
141
  }
132
142
  return throwUndefinedProviderError();
133
143
  }
144
+
145
+ /* #####################
146
+ * Storage Implementation
147
+ * ##################### */
148
+ export const uploadFile = (file: UploadFile): Promise<unknown> => {
149
+ if (provider === "firebase") {
150
+ return uploadFirestorageFile(file);
151
+ }
152
+ if (provider === "mock") {
153
+ return uploadStorageFileMock(file)
154
+ }
155
+ return throwUndefinedProviderError();
156
+ }
@@ -96,6 +96,15 @@ export interface StoreConfig {
96
96
  effects: Array<any>
97
97
  }
98
98
 
99
+ export interface FileStorage {
100
+ name: string,
101
+ references: string[]
102
+ }
103
+
104
+ export interface FileStorageConfig {
105
+ storage: FileStorage[],
106
+ }
107
+
99
108
  export interface AppConfiguration {
100
109
  serviceProvider?: ServiceProviderConfiguration,
101
110
  mock?: {
@@ -105,7 +114,16 @@ export interface AppConfiguration {
105
114
  navigationConfigParam: NavigationConfig;
106
115
  storeConfigParam?: StoreConfig;
107
116
  firebaseConfig?: FirebaseOptions;
117
+ storageConfig?: FileStorageConfig;
108
118
  functionsConfig?: FunctionsConfig;
109
119
  }
110
120
 
121
+ export interface UploadFile {
122
+ fileName: string,
123
+ base64DataURL:string,
124
+ storageName?: string
125
+ referenceKey?: string
126
+ subFolderName?: string,
127
+ }
128
+
111
129