cloudcommerce 0.0.56 → 0.0.59
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/CHANGELOG.md +20 -0
- package/package.json +1 -1
- package/packages/api/package.json +1 -1
- package/packages/apps/discounts/package.json +1 -1
- package/packages/apps/tiny-erp/README.md +1 -1
- package/packages/apps/tiny-erp/package.json +3 -3
- package/packages/apps/tiny-erp/src/firebase.ts +0 -0
- package/packages/apps/tiny-erp/tsconfig.json +1 -1
- package/packages/cli/config/firebase.json +6 -3
- package/packages/cli/lib/index.js +23 -4
- package/packages/cli/lib/{config-gcloud.js → setup-gcloud.js} +2 -2
- package/packages/cli/lib/setup-gh.js +59 -0
- package/packages/cli/package.json +2 -1
- package/packages/cli/src/index.ts +30 -3
- package/packages/cli/src/{config-gcloud.ts → setup-gcloud.ts} +2 -2
- package/packages/cli/src/setup-gh.ts +83 -0
- package/packages/events/package.json +2 -1
- package/packages/firebase/lib/config.js +1 -1
- package/packages/firebase/lib/config.js.map +1 -1
- package/packages/firebase/lib/handlers/check-store-events.d.ts +1 -1
- package/packages/firebase/lib/handlers/check-store-events.js +51 -10
- package/packages/firebase/lib/handlers/check-store-events.js.map +1 -1
- package/packages/firebase/package.json +2 -1
- package/packages/firebase/src/config.ts +1 -1
- package/packages/firebase/src/handlers/check-store-events.ts +59 -10
- package/packages/modules/package.json +1 -1
- package/packages/passport/package.json +1 -1
- package/packages/ssr/package.json +1 -1
- package/packages/storefront/package.json +3 -2
- package/packages/types/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.0.59](https://github.com/ecomplus/cloud-commerce/compare/v0.0.58...v0.0.59) (2022-08-24)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **cli:** Use `GITHUB_TOKEN` env to auto set secrets on setup ([#43](https://github.com/ecomplus/cloud-commerce/issues/43)) ([8949070](https://github.com/ecomplus/cloud-commerce/commit/89490703cba52affdbb69c63d8b459cb609f5130))
|
|
11
|
+
* **events:** Start publishing PubSub messages for each topic/app/event [[#29](https://github.com/ecomplus/cloud-commerce/issues/29)] ([9575d25](https://github.com/ecomplus/cloud-commerce/commit/9575d25d4ca27fcc19acbd0118b0140f8b484316))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* **cli:** Do not create `GH_TOKEN` secret (set by default) ([8e50e37](https://github.com/ecomplus/cloud-commerce/commit/8e50e371477bdf67ec0cef380f2c6488d3d588a5))
|
|
17
|
+
* **deps:** Add `@google-cloud/pubsub` to core `@cloudcommerce/firebase` dependencies ([0b35b0e](https://github.com/ecomplus/cloud-commerce/commit/0b35b0edb560329a21869e8b6a75abaed9c4cd34))
|
|
18
|
+
* **events:** Save last run state and timestamp to Firestore ([7183a55](https://github.com/ecomplus/cloud-commerce/commit/7183a55694ca0e5cc6968be9ca4e965772937e2a))
|
|
19
|
+
* Set default GCloud region to `southamerica-east1` (São Paulo) ([212d04d](https://github.com/ecomplus/cloud-commerce/commit/212d04d72ace4cffe54489dae5b74c2dbfa4e0d0))
|
|
20
|
+
|
|
21
|
+
### [0.0.58](https://github.com/ecomplus/cloud-commerce/compare/v0.0.57...v0.0.58) (2022-08-23)
|
|
22
|
+
|
|
23
|
+
### [0.0.57](https://github.com/ecomplus/cloud-commerce/compare/v0.0.56...v0.0.57) (2022-08-23)
|
|
24
|
+
|
|
5
25
|
### [0.0.56](https://github.com/ecomplus/cloud-commerce/compare/v0.0.55...v0.0.56) (2022-08-23)
|
|
6
26
|
|
|
7
27
|
### [0.0.55](https://github.com/ecomplus/cloud-commerce/compare/v0.0.54...v0.0.55) (2022-08-23)
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcommerce",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "Open fair-code headless commerce platform: API-first, microservices based, event driven and cloud native",
|
|
6
6
|
"main": "packages/api/lib/index.js",
|
|
7
7
|
"author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
# `@cloudcommerce/tiny`
|
|
1
|
+
# `@cloudcommerce/tiny-erp`
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/app-tiny-erp",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/ecomplus/cloud-commerce.git",
|
|
10
|
-
"directory": "packages/tiny"
|
|
10
|
+
"directory": "packages/apps/tiny-erp"
|
|
11
11
|
},
|
|
12
12
|
"author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
|
|
13
13
|
"license": "Apache 2.0 with Commons Clause",
|
|
14
14
|
"bugs": {
|
|
15
15
|
"url": "https://github.com/ecomplus/cloud-commerce/issues"
|
|
16
16
|
},
|
|
17
|
-
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/tiny#readme",
|
|
17
|
+
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/apps/tiny-erp#readme",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "echo '@ecomplus/tiny-erp'"
|
|
20
20
|
},
|
|
File without changes
|
|
@@ -40,15 +40,18 @@
|
|
|
40
40
|
"rewrites": [
|
|
41
41
|
{
|
|
42
42
|
"source": "/api/modules/**",
|
|
43
|
-
"function": "modules"
|
|
43
|
+
"function": "modules",
|
|
44
|
+
"region": "southamerica-east1"
|
|
44
45
|
},
|
|
45
46
|
{
|
|
46
47
|
"source": "/api/passport/**",
|
|
47
|
-
"function": "passport"
|
|
48
|
+
"function": "passport",
|
|
49
|
+
"region": "southamerica-east1"
|
|
48
50
|
},
|
|
49
51
|
{
|
|
50
52
|
"source": "**/!(*(*.)js|*(*.)css|*(*.)ico|*(*.)png|*(*.)gif|*(*.)jpg|*(*.)jpeg|*(*.)webp|*(*.)avif|*(*.)svg|*(*.)woff|*(*.)woff2|*(*.)otf|*(*.)ttf|*(*.)eot)",
|
|
51
|
-
"function": "ssr"
|
|
53
|
+
"function": "ssr",
|
|
54
|
+
"region": "southamerica-east1"
|
|
52
55
|
}
|
|
53
56
|
],
|
|
54
57
|
"cleanUrls": true
|
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
} from 'zx';
|
|
6
6
|
import login from './login.js';
|
|
7
7
|
import build from './build.js';
|
|
8
|
-
import { siginGcloudAndSetIAM,
|
|
8
|
+
import { siginGcloudAndSetIAM, createServiceAccountKey } from './setup-gcloud.js';
|
|
9
|
+
import createGhSecrets from './setup-gh.js';
|
|
9
10
|
|
|
10
|
-
const { FIREBASE_PROJECT_ID, GOOGLE_APPLICATION_CREDENTIALS } = process.env;
|
|
11
|
+
const { FIREBASE_PROJECT_ID, GOOGLE_APPLICATION_CREDENTIALS, GITHUB_TOKEN } = process.env;
|
|
11
12
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
12
13
|
const pwd = process.cwd();
|
|
13
14
|
let projectId = FIREBASE_PROJECT_ID;
|
|
@@ -29,7 +30,7 @@ if (projectId) {
|
|
|
29
30
|
const firebaserc = fs.readJSONSync(path.join(pwd, '.firebaserc'));
|
|
30
31
|
projectId = firebaserc.projects.default;
|
|
31
32
|
} catch (e) {
|
|
32
|
-
projectId = 'ecom2-
|
|
33
|
+
projectId = 'ecom2-002';
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
}
|
|
@@ -102,11 +103,29 @@ ECOM_STORE_ID=${storeId}
|
|
|
102
103
|
if (argv.gcloud !== false) {
|
|
103
104
|
try {
|
|
104
105
|
await siginGcloudAndSetIAM(projectId, pwd);
|
|
105
|
-
serviceAccountJSON = await
|
|
106
|
+
serviceAccountJSON = await createServiceAccountKey(projectId, pwd);
|
|
106
107
|
} catch (e) {
|
|
107
108
|
//
|
|
108
109
|
}
|
|
109
110
|
}
|
|
111
|
+
let hasCreatedAllSecrets = false;
|
|
112
|
+
if (GITHUB_TOKEN && argv.github !== false) {
|
|
113
|
+
try {
|
|
114
|
+
hasCreatedAllSecrets = await createGhSecrets(apiKey, authenticationId, serviceAccountJSON, GITHUB_TOKEN);
|
|
115
|
+
} catch (e) {
|
|
116
|
+
//
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (hasCreatedAllSecrets) {
|
|
120
|
+
return echo`
|
|
121
|
+
****
|
|
122
|
+
|
|
123
|
+
CloudCommerce setup completed successfully.
|
|
124
|
+
Your store repository on GitHub is ready, the first deploy will automatically start with GH Actions.
|
|
125
|
+
|
|
126
|
+
-- More info at https://github.com/ecomplus/store#getting-started
|
|
127
|
+
`;
|
|
128
|
+
}
|
|
110
129
|
return echo`
|
|
111
130
|
****
|
|
112
131
|
|
|
@@ -78,7 +78,7 @@ const siginGcloudAndSetIAM = async (projectId, pwd) => {
|
|
|
78
78
|
}
|
|
79
79
|
return null;
|
|
80
80
|
};
|
|
81
|
-
const
|
|
81
|
+
const createServiceAccountKey = async (projectId, pwd) => {
|
|
82
82
|
try {
|
|
83
83
|
const pathFileKey = path.join(pwd, '.cloudcommerce', 'serviceAccountKey.json');
|
|
84
84
|
await $`gcloud iam service-accounts keys create ${pathFileKey} \
|
|
@@ -91,4 +91,4 @@ const createKeyServiceAccount = async (projectId, pwd) => {
|
|
|
91
91
|
|
|
92
92
|
export default siginGcloudAndSetIAM;
|
|
93
93
|
|
|
94
|
-
export { siginGcloudAndSetIAM,
|
|
94
|
+
export { siginGcloudAndSetIAM, createServiceAccountKey };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { fetch, $ } from 'zx';
|
|
2
|
+
import libsodium from 'libsodium-wrappers';
|
|
3
|
+
|
|
4
|
+
const getRemoteRepo = async () => {
|
|
5
|
+
try {
|
|
6
|
+
return (await $`git config --get remote.origin.url`).stdout
|
|
7
|
+
.replace(/.*github.com[/:]/, '')
|
|
8
|
+
.replace('.git', '')
|
|
9
|
+
.replace('\n', '');
|
|
10
|
+
} catch (e) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const createGhSecrets = async (ecomApiKey, ecomAuthentication, firebaseServiceAccount, ghToken, ghRepo) => {
|
|
15
|
+
const remoteRepo = ghRepo || await getRemoteRepo();
|
|
16
|
+
if (!remoteRepo) {
|
|
17
|
+
throw new Error("Can't define remote Git repository");
|
|
18
|
+
}
|
|
19
|
+
const baseUrl = `https://api.github.com/repos/${remoteRepo}/actions/secrets`;
|
|
20
|
+
const fetchGhSecrets = async (resource, body, method = 'GET') => {
|
|
21
|
+
const url = `${baseUrl}${resource}`;
|
|
22
|
+
const headers = {
|
|
23
|
+
Accept: 'application/vnd.github+json',
|
|
24
|
+
Authorization: `token ${ghToken}`,
|
|
25
|
+
};
|
|
26
|
+
return fetch(url, {
|
|
27
|
+
method,
|
|
28
|
+
headers,
|
|
29
|
+
body,
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
// https:// docs.github.com/pt/rest/actions/secrets#get-a-repository-public-key
|
|
33
|
+
const ghPublicKey = await (await fetchGhSecrets('/public-key')).json();
|
|
34
|
+
const ghKeyBuffer = Buffer.from(ghPublicKey.key, 'base64');
|
|
35
|
+
await libsodium.ready;
|
|
36
|
+
const createGhSecret = async (secretName, secretValue) => {
|
|
37
|
+
// https://docs.github.com/pt/rest/actions/secrets#example-encrypting-a-secret-using-nodejs
|
|
38
|
+
// Encryption example: https://github.com/github/tweetsodium
|
|
39
|
+
const encryptedBytes = libsodium.crypto_box_seal(Buffer.from(secretValue), ghKeyBuffer);
|
|
40
|
+
const body = {
|
|
41
|
+
encrypted_value: Buffer.from(encryptedBytes).toString('base64'),
|
|
42
|
+
key_id: ghPublicKey.key_id,
|
|
43
|
+
};
|
|
44
|
+
return fetchGhSecrets(`/${secretName}`, JSON.stringify(body), 'PUT');
|
|
45
|
+
};
|
|
46
|
+
try {
|
|
47
|
+
await createGhSecret('ECOM_API_KEY', ecomApiKey);
|
|
48
|
+
await createGhSecret('ECOM_AUTHENTICATION_ID', ecomAuthentication);
|
|
49
|
+
if (firebaseServiceAccount) {
|
|
50
|
+
await createGhSecret('FIREBASE_SERVICE_ACCOUNT', firebaseServiceAccount);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
} catch (e) {
|
|
54
|
+
//
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default createGhSecrets;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/cli",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce CLI tools",
|
|
6
6
|
"bin": {
|
|
7
7
|
"cloudcommerce": "./bin/run.mjs"
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@cloudcommerce/api": "workspace:*",
|
|
30
|
+
"libsodium-wrappers": "^0.7.10",
|
|
30
31
|
"md5": "^2.3.0",
|
|
31
32
|
"zx": "^7.0.8"
|
|
32
33
|
}
|
|
@@ -9,11 +9,13 @@ import {
|
|
|
9
9
|
} from 'zx';
|
|
10
10
|
import login from './login';
|
|
11
11
|
import build from './build';
|
|
12
|
-
import { siginGcloudAndSetIAM,
|
|
12
|
+
import { siginGcloudAndSetIAM, createServiceAccountKey } from './setup-gcloud';
|
|
13
|
+
import createGhSecrets from './setup-gh';
|
|
13
14
|
|
|
14
15
|
const {
|
|
15
16
|
FIREBASE_PROJECT_ID,
|
|
16
17
|
GOOGLE_APPLICATION_CREDENTIALS,
|
|
18
|
+
GITHUB_TOKEN,
|
|
17
19
|
} = process.env;
|
|
18
20
|
|
|
19
21
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
@@ -41,7 +43,7 @@ if (projectId) {
|
|
|
41
43
|
const firebaserc = fs.readJSONSync(path.join(pwd, '.firebaserc'));
|
|
42
44
|
projectId = firebaserc.projects.default;
|
|
43
45
|
} catch (e) {
|
|
44
|
-
projectId = 'ecom2-
|
|
46
|
+
projectId = 'ecom2-002';
|
|
45
47
|
}
|
|
46
48
|
}
|
|
47
49
|
}
|
|
@@ -103,6 +105,7 @@ ECOM_API_KEY=${apiKey}
|
|
|
103
105
|
ECOM_STORE_ID=${storeId}
|
|
104
106
|
`,
|
|
105
107
|
);
|
|
108
|
+
|
|
106
109
|
if (argv.deploy !== false) {
|
|
107
110
|
await $firebase('deploy');
|
|
108
111
|
}
|
|
@@ -111,6 +114,7 @@ ECOM_STORE_ID=${storeId}
|
|
|
111
114
|
path.join(pwd, 'functions', 'config.json'),
|
|
112
115
|
JSON.stringify({ storeId }, null, 2),
|
|
113
116
|
);
|
|
117
|
+
|
|
114
118
|
await build();
|
|
115
119
|
try {
|
|
116
120
|
await $`git add .firebaserc functions/config.json`;
|
|
@@ -124,12 +128,35 @@ ECOM_STORE_ID=${storeId}
|
|
|
124
128
|
if (argv.gcloud !== false) {
|
|
125
129
|
try {
|
|
126
130
|
await siginGcloudAndSetIAM(projectId as string, pwd);
|
|
127
|
-
serviceAccountJSON = await
|
|
131
|
+
serviceAccountJSON = await createServiceAccountKey(projectId as string, pwd);
|
|
132
|
+
} catch (e) {
|
|
133
|
+
//
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let hasCreatedAllSecrets = false;
|
|
137
|
+
if (GITHUB_TOKEN && argv.github !== false) {
|
|
138
|
+
try {
|
|
139
|
+
hasCreatedAllSecrets = await createGhSecrets(
|
|
140
|
+
apiKey,
|
|
141
|
+
authenticationId,
|
|
142
|
+
serviceAccountJSON,
|
|
143
|
+
GITHUB_TOKEN,
|
|
144
|
+
);
|
|
128
145
|
} catch (e) {
|
|
129
146
|
//
|
|
130
147
|
}
|
|
131
148
|
}
|
|
132
149
|
|
|
150
|
+
if (hasCreatedAllSecrets) {
|
|
151
|
+
return echo`
|
|
152
|
+
****
|
|
153
|
+
|
|
154
|
+
CloudCommerce setup completed successfully.
|
|
155
|
+
Your store repository on GitHub is ready, the first deploy will automatically start with GH Actions.
|
|
156
|
+
|
|
157
|
+
-- More info at https://github.com/ecomplus/store#getting-started
|
|
158
|
+
`;
|
|
159
|
+
}
|
|
133
160
|
return echo`
|
|
134
161
|
****
|
|
135
162
|
|
|
@@ -84,7 +84,7 @@ const siginGcloudAndSetIAM = async (projectId: string, pwd: string) => {
|
|
|
84
84
|
return null;
|
|
85
85
|
};
|
|
86
86
|
|
|
87
|
-
const
|
|
87
|
+
const createServiceAccountKey = async (projectId: string, pwd: string) => {
|
|
88
88
|
try {
|
|
89
89
|
const pathFileKey = path.join(pwd, '.cloudcommerce', 'serviceAccountKey.json');
|
|
90
90
|
await $`gcloud iam service-accounts keys create ${pathFileKey} \
|
|
@@ -99,5 +99,5 @@ export default siginGcloudAndSetIAM;
|
|
|
99
99
|
|
|
100
100
|
export {
|
|
101
101
|
siginGcloudAndSetIAM,
|
|
102
|
-
|
|
102
|
+
createServiceAccountKey,
|
|
103
103
|
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { fetch, $ } from 'zx';
|
|
2
|
+
import libsodium from 'libsodium-wrappers';
|
|
3
|
+
|
|
4
|
+
const getRemoteRepo = async () => {
|
|
5
|
+
try {
|
|
6
|
+
return (await $`git config --get remote.origin.url`).stdout
|
|
7
|
+
.replace(/.*github.com[/:]/, '')
|
|
8
|
+
.replace('.git', '')
|
|
9
|
+
.replace('\n', '');
|
|
10
|
+
} catch (e) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createGhSecrets = async (
|
|
16
|
+
ecomApiKey: string,
|
|
17
|
+
ecomAuthentication: string,
|
|
18
|
+
firebaseServiceAccount: string | null,
|
|
19
|
+
ghToken: string,
|
|
20
|
+
ghRepo?: string,
|
|
21
|
+
) => {
|
|
22
|
+
const remoteRepo = ghRepo || await getRemoteRepo();
|
|
23
|
+
if (!remoteRepo) {
|
|
24
|
+
throw new Error("Can't define remote Git repository");
|
|
25
|
+
}
|
|
26
|
+
const baseUrl = `https://api.github.com/repos/${remoteRepo}/actions/secrets`;
|
|
27
|
+
|
|
28
|
+
const fetchGhSecrets = async (
|
|
29
|
+
resource: string,
|
|
30
|
+
body?: string,
|
|
31
|
+
method: string = 'GET',
|
|
32
|
+
) => {
|
|
33
|
+
const url = `${baseUrl}${resource}`;
|
|
34
|
+
const headers = {
|
|
35
|
+
Accept: 'application/vnd.github+json',
|
|
36
|
+
Authorization: `token ${ghToken}`,
|
|
37
|
+
};
|
|
38
|
+
return fetch(url, {
|
|
39
|
+
method,
|
|
40
|
+
headers,
|
|
41
|
+
body,
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// https:// docs.github.com/pt/rest/actions/secrets#get-a-repository-public-key
|
|
46
|
+
const ghPublicKey = await (await fetchGhSecrets('/public-key')).json() as {
|
|
47
|
+
key_id: string,
|
|
48
|
+
key: string,
|
|
49
|
+
};
|
|
50
|
+
const ghKeyBuffer = Buffer.from(ghPublicKey.key, 'base64');
|
|
51
|
+
await libsodium.ready;
|
|
52
|
+
|
|
53
|
+
const createGhSecret = async (
|
|
54
|
+
secretName: string,
|
|
55
|
+
secretValue: string,
|
|
56
|
+
) => {
|
|
57
|
+
// https://docs.github.com/pt/rest/actions/secrets#example-encrypting-a-secret-using-nodejs
|
|
58
|
+
// Encryption example: https://github.com/github/tweetsodium
|
|
59
|
+
const encryptedBytes = libsodium.crypto_box_seal(
|
|
60
|
+
Buffer.from(secretValue),
|
|
61
|
+
ghKeyBuffer,
|
|
62
|
+
);
|
|
63
|
+
const body = {
|
|
64
|
+
encrypted_value: Buffer.from(encryptedBytes).toString('base64'),
|
|
65
|
+
key_id: ghPublicKey.key_id,
|
|
66
|
+
};
|
|
67
|
+
return fetchGhSecrets(`/${secretName}`, JSON.stringify(body), 'PUT');
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
await createGhSecret('ECOM_API_KEY', ecomApiKey);
|
|
72
|
+
await createGhSecret('ECOM_AUTHENTICATION_ID', ecomAuthentication);
|
|
73
|
+
if (firebaseServiceAccount) {
|
|
74
|
+
await createGhSecret('FIREBASE_SERVICE_ACCOUNT', firebaseServiceAccount);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
} catch (e) {
|
|
78
|
+
//
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export default createGhSecrets;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/events",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce app events",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@cloudcommerce/api": "workspace:*",
|
|
27
|
+
"@cloudcommerce/app-tiny-erp": "workspace:*",
|
|
27
28
|
"@cloudcommerce/firebase": "workspace:*",
|
|
28
29
|
"firebase-admin": "^11.0.1",
|
|
29
30
|
"firebase-functions": "^3.22.0",
|
|
@@ -17,7 +17,7 @@ const self = {
|
|
|
17
17
|
countryCode: env.ECOM_COUNTRY_CODE || DEFAULT_COUNTRY_CODE,
|
|
18
18
|
storeId: Number(env.ECOM_STORE_ID),
|
|
19
19
|
httpsFunctionOptions: {
|
|
20
|
-
region: env.DEPLOY_REGION || '
|
|
20
|
+
region: env.DEPLOY_REGION || 'southamerica-east1',
|
|
21
21
|
},
|
|
22
22
|
apps: {
|
|
23
23
|
discounts: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,aAAa;AACb,MAAM,GAAG,GAA8B,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,EAAE,GAAG,CAAC;OAC/E,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC;OACtC,EAAE,CAAC;AAER,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;AAE9B,MAAM,IAAI,GAAG;IACX,QAAQ,EAAE;QACR,KAAK,EAAE,8BAA8B;QACrC,IAAI,EAAE,GAAG,CAAC,SAAS,IAAI,YAAY;QACnC,QAAQ,EAAE,GAAG,CAAC,aAAa,IAAI,gBAAgB;QAC/C,cAAc,EAAE,GAAG,CAAC,oBAAoB,IAAI,uBAAuB;QACnE,WAAW,EAAE,GAAG,CAAC,iBAAiB,IAAI,oBAAoB;QAC1D,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC;QAClC,oBAAoB,EAAE;YACpB,MAAM,EAAE,GAAG,CAAC,aAAa,IAAI,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,aAAa;AACb,MAAM,GAAG,GAA8B,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,EAAE,GAAG,CAAC;OAC/E,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC;OACtC,EAAE,CAAC;AAER,MAAM,SAAS,GAAG,SAAS,EAAE,CAAC;AAE9B,MAAM,IAAI,GAAG;IACX,QAAQ,EAAE;QACR,KAAK,EAAE,8BAA8B;QACrC,IAAI,EAAE,GAAG,CAAC,SAAS,IAAI,YAAY;QACnC,QAAQ,EAAE,GAAG,CAAC,aAAa,IAAI,gBAAgB;QAC/C,cAAc,EAAE,GAAG,CAAC,oBAAoB,IAAI,uBAAuB;QACnE,WAAW,EAAE,GAAG,CAAC,iBAAiB,IAAI,oBAAoB;QAC1D,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC;QAClC,oBAAoB,EAAE;YACpB,MAAM,EAAE,GAAG,CAAC,aAAa,IAAI,oBAAoB;SAClD;QACD,IAAI,EAAE;YACJ,SAAS,EAAE;gBACT,KAAK,EAAE,IAAI;aACZ;YACD,OAAO,EAAE;gBACP,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE;oBACN,qBAAqB;oBACrB,cAAc;oBACd,mBAAmB;iBACA;aACtB;SACF;KACF;CACF,CAAC;AAEF,eAAe;IACb,GAAG;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,GAAG,CAAC,MAAM;QACR,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,OAAO,EAAE;YAClB,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC;SACpC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: () => Promise<
|
|
1
|
+
declare const _default: () => Promise<FirebaseFirestore.WriteResult>;
|
|
2
2
|
export default _default;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-unresolved
|
|
2
|
+
import { getFirestore } from 'firebase-admin/firestore';
|
|
1
3
|
import logger from 'firebase-functions/lib/logger';
|
|
4
|
+
import { PubSub } from '@google-cloud/pubsub';
|
|
2
5
|
import api from '@cloudcommerce/api';
|
|
3
6
|
import getEnv from '../env.js';
|
|
4
7
|
import config from '../config.js';
|
|
5
8
|
|
|
6
|
-
const parseEventsTopic = (eventsTopic) => {
|
|
9
|
+
const parseEventsTopic = (eventsTopic, baseApiEventsFilter) => {
|
|
7
10
|
const [resource, eventName] = eventsTopic.split('-');
|
|
8
11
|
const params = {};
|
|
9
|
-
const bodySet = {};
|
|
12
|
+
const bodySet = { ...baseApiEventsFilter };
|
|
10
13
|
if (eventName === 'new') {
|
|
11
14
|
params.action = 'create';
|
|
12
15
|
} else {
|
|
@@ -50,8 +53,30 @@ const parseEventsTopic = (eventsTopic) => {
|
|
|
50
53
|
});
|
|
51
54
|
return { resource, params };
|
|
52
55
|
};
|
|
56
|
+
const pubSubClient = new PubSub();
|
|
57
|
+
const tryPubSubPublish = (topicName, messageObj, retries = 0) => {
|
|
58
|
+
pubSubClient.topic(topicName).publishMessage(messageObj)
|
|
59
|
+
.catch((err) => {
|
|
60
|
+
// eslint-disable-next-line no-param-reassign
|
|
61
|
+
err.retries = retries;
|
|
62
|
+
logger.error(err);
|
|
63
|
+
if (retries <= 3) {
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
tryPubSubPublish(topicName, messageObj, retries + 1);
|
|
66
|
+
}, 1000 * (2 ** retries));
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
};
|
|
53
70
|
|
|
54
71
|
export default async () => {
|
|
72
|
+
const timestamp = Date.now();
|
|
73
|
+
const documentRef = getFirestore().doc('storeEvents/last');
|
|
74
|
+
const lastRunTimestamp = (await documentRef.get()).get('timestamp')
|
|
75
|
+
|| Date.now() - 1000 * 60 * 5;
|
|
76
|
+
const baseApiEventsFilter = {
|
|
77
|
+
'timestamp>': new Date(lastRunTimestamp - 1).toISOString(),
|
|
78
|
+
'timestamp<': new Date(timestamp).toISOString(),
|
|
79
|
+
};
|
|
55
80
|
const { apps } = config.get();
|
|
56
81
|
const { apiAuth } = getEnv();
|
|
57
82
|
const subscribersApps = [];
|
|
@@ -61,25 +86,25 @@ export default async () => {
|
|
|
61
86
|
subscribersApps.push(appObj);
|
|
62
87
|
}
|
|
63
88
|
});
|
|
64
|
-
const
|
|
89
|
+
const activeAppsIds = (await api.get('applications', {
|
|
65
90
|
params: {
|
|
66
91
|
state: 'active',
|
|
67
92
|
app_id: subscribersApps.map(({ appId }) => appId),
|
|
68
93
|
fields: 'app_id',
|
|
69
94
|
},
|
|
70
|
-
})).data.result;
|
|
71
|
-
logger.info({ activeSubscribersApps });
|
|
95
|
+
})).data.result.map((app) => app.app_id);
|
|
72
96
|
const listenedEvents = [];
|
|
73
97
|
subscribersApps.forEach(({ appId, events }) => {
|
|
74
|
-
if (
|
|
98
|
+
if (activeAppsIds.includes(appId)) {
|
|
75
99
|
events.forEach((eventsTopic) => {
|
|
76
|
-
listenedEvents.
|
|
100
|
+
if (!listenedEvents.includes(eventsTopic)) {
|
|
101
|
+
listenedEvents.push(eventsTopic);
|
|
102
|
+
}
|
|
77
103
|
});
|
|
78
104
|
}
|
|
79
105
|
});
|
|
80
|
-
logger.info({ listenedEvents });
|
|
81
106
|
listenedEvents.forEach(async (eventsTopic) => {
|
|
82
|
-
const { resource, params } = parseEventsTopic(eventsTopic);
|
|
107
|
+
const { resource, params } = parseEventsTopic(eventsTopic, baseApiEventsFilter);
|
|
83
108
|
let { data: { result } } = await api.get(`events/${resource}`, {
|
|
84
109
|
...apiAuth,
|
|
85
110
|
params,
|
|
@@ -99,8 +124,24 @@ export default async () => {
|
|
|
99
124
|
if (typeof middleware === 'function') {
|
|
100
125
|
result = await middleware(resource, result);
|
|
101
126
|
}
|
|
127
|
+
result.forEach((apiEvent) => {
|
|
128
|
+
subscribersApps.forEach(({ appId, events }) => {
|
|
129
|
+
if (events.includes(eventsTopic) && activeAppsIds.includes(appId)) {
|
|
130
|
+
const topicName = `app${appId}_${eventsTopic}`;
|
|
131
|
+
const messageObj = {
|
|
132
|
+
messageId: `${eventsTopic}_${apiEvent.timestamp}`,
|
|
133
|
+
json: apiEvent,
|
|
134
|
+
};
|
|
135
|
+
tryPubSubPublish(topicName, messageObj);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
});
|
|
102
139
|
logger.info(`> '${eventsTopic}' events: `, result);
|
|
103
140
|
});
|
|
104
|
-
return
|
|
141
|
+
return documentRef.set({
|
|
142
|
+
timestamp,
|
|
143
|
+
activeAppsIds,
|
|
144
|
+
listenedEvents,
|
|
145
|
+
});
|
|
105
146
|
};
|
|
106
147
|
// # sourceMappingURL=check-store-events.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-store-events.js","sourceRoot":"","sources":["../../src/handlers/check-store-events.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,+BAA+B,CAAC;AACnD,OAAO,GAAkB,MAAM,oBAAoB,CAAC;AACpD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B,MAAM,gBAAgB,GAAG,
|
|
1
|
+
{"version":3,"file":"check-store-events.js","sourceRoot":"","sources":["../../src/handlers/check-store-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/firebase",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce on Firebase",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/index.d.ts",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@cloudcommerce/api": "workspace:*",
|
|
30
30
|
"@fastify/deepmerge": "^1.1.0",
|
|
31
|
+
"@google-cloud/pubsub": "^3.1.0",
|
|
31
32
|
"firebase-admin": "^11.0.1",
|
|
32
33
|
"firebase-functions": "^3.22.0",
|
|
33
34
|
"node-fetch": "^3.2.10",
|
|
@@ -23,7 +23,7 @@ const self = {
|
|
|
23
23
|
countryCode: env.ECOM_COUNTRY_CODE || DEFAULT_COUNTRY_CODE,
|
|
24
24
|
storeId: Number(env.ECOM_STORE_ID),
|
|
25
25
|
httpsFunctionOptions: {
|
|
26
|
-
region: env.DEPLOY_REGION || '
|
|
26
|
+
region: env.DEPLOY_REGION || 'southamerica-east1',
|
|
27
27
|
},
|
|
28
28
|
apps: {
|
|
29
29
|
discounts: {
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import type { Resource, AppEventsTopic } from '@cloudcommerce/types';
|
|
2
|
+
// eslint-disable-next-line import/no-unresolved
|
|
3
|
+
import { getFirestore } from 'firebase-admin/firestore';
|
|
2
4
|
import logger from 'firebase-functions/lib/logger';
|
|
5
|
+
import { PubSub } from '@google-cloud/pubsub';
|
|
3
6
|
import api, { ApiConfig } from '@cloudcommerce/api';
|
|
4
7
|
import getEnv from '../env';
|
|
5
8
|
import config from '../config';
|
|
6
9
|
|
|
7
|
-
const parseEventsTopic = (
|
|
10
|
+
const parseEventsTopic = (
|
|
11
|
+
eventsTopic: AppEventsTopic,
|
|
12
|
+
baseApiEventsFilter: Record<string, string>,
|
|
13
|
+
) => {
|
|
8
14
|
const [resource, eventName] = eventsTopic.split('-');
|
|
9
15
|
const params: ApiConfig['params'] = {};
|
|
10
|
-
const bodySet: { [key: string]: any } = {};
|
|
16
|
+
const bodySet: { [key: string]: any } = { ...baseApiEventsFilter };
|
|
11
17
|
if (eventName === 'new') {
|
|
12
18
|
params.action = 'create';
|
|
13
19
|
} else {
|
|
@@ -55,7 +61,34 @@ const parseEventsTopic = (eventsTopic: AppEventsTopic) => {
|
|
|
55
61
|
};
|
|
56
62
|
};
|
|
57
63
|
|
|
64
|
+
const pubSubClient = new PubSub();
|
|
65
|
+
const tryPubSubPublish = (
|
|
66
|
+
topicName: string,
|
|
67
|
+
messageObj: { messageId: string, json: any },
|
|
68
|
+
retries = 0,
|
|
69
|
+
) => {
|
|
70
|
+
pubSubClient.topic(topicName).publishMessage(messageObj)
|
|
71
|
+
.catch((err) => {
|
|
72
|
+
// eslint-disable-next-line no-param-reassign
|
|
73
|
+
err.retries = retries;
|
|
74
|
+
logger.error(err);
|
|
75
|
+
if (retries <= 3) {
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
tryPubSubPublish(topicName, messageObj, retries + 1);
|
|
78
|
+
}, 1000 * (2 ** retries));
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
58
83
|
export default async () => {
|
|
84
|
+
const timestamp = Date.now();
|
|
85
|
+
const documentRef = getFirestore().doc('storeEvents/last');
|
|
86
|
+
const lastRunTimestamp: number = (await documentRef.get()).get('timestamp')
|
|
87
|
+
|| Date.now() - 1000 * 60 * 5;
|
|
88
|
+
const baseApiEventsFilter = {
|
|
89
|
+
'timestamp>': new Date(lastRunTimestamp - 1).toISOString(),
|
|
90
|
+
'timestamp<': new Date(timestamp).toISOString(),
|
|
91
|
+
};
|
|
59
92
|
const { apps } = config.get();
|
|
60
93
|
const { apiAuth } = getEnv();
|
|
61
94
|
const subscribersApps: Array<{ appId: number, events: AppEventsTopic[] }> = [];
|
|
@@ -65,25 +98,25 @@ export default async () => {
|
|
|
65
98
|
subscribersApps.push(appObj);
|
|
66
99
|
}
|
|
67
100
|
});
|
|
68
|
-
const
|
|
101
|
+
const activeAppsIds = (await api.get('applications', {
|
|
69
102
|
params: {
|
|
70
103
|
state: 'active',
|
|
71
104
|
app_id: subscribersApps.map(({ appId }) => appId),
|
|
72
105
|
fields: 'app_id',
|
|
73
106
|
},
|
|
74
|
-
})).data.result;
|
|
75
|
-
logger.info({ activeSubscribersApps });
|
|
107
|
+
})).data.result.map((app) => app.app_id);
|
|
76
108
|
const listenedEvents: AppEventsTopic[] = [];
|
|
77
109
|
subscribersApps.forEach(({ appId, events }) => {
|
|
78
|
-
if (
|
|
110
|
+
if (activeAppsIds.includes(appId)) {
|
|
79
111
|
events.forEach((eventsTopic) => {
|
|
80
|
-
listenedEvents.
|
|
112
|
+
if (!listenedEvents.includes(eventsTopic)) {
|
|
113
|
+
listenedEvents.push(eventsTopic);
|
|
114
|
+
}
|
|
81
115
|
});
|
|
82
116
|
}
|
|
83
117
|
});
|
|
84
|
-
logger.info({ listenedEvents });
|
|
85
118
|
listenedEvents.forEach(async (eventsTopic) => {
|
|
86
|
-
const { resource, params } = parseEventsTopic(eventsTopic);
|
|
119
|
+
const { resource, params } = parseEventsTopic(eventsTopic, baseApiEventsFilter);
|
|
87
120
|
let { data: { result } } = await api.get(`events/${resource}`, {
|
|
88
121
|
...apiAuth,
|
|
89
122
|
params,
|
|
@@ -103,7 +136,23 @@ export default async () => {
|
|
|
103
136
|
if (typeof middleware === 'function') {
|
|
104
137
|
result = await middleware(resource, result);
|
|
105
138
|
}
|
|
139
|
+
result.forEach((apiEvent) => {
|
|
140
|
+
subscribersApps.forEach(({ appId, events }) => {
|
|
141
|
+
if (events.includes(eventsTopic) && activeAppsIds.includes(appId)) {
|
|
142
|
+
const topicName = `app${appId}_${eventsTopic}`;
|
|
143
|
+
const messageObj = {
|
|
144
|
+
messageId: `${eventsTopic}_${apiEvent.timestamp}`,
|
|
145
|
+
json: apiEvent,
|
|
146
|
+
};
|
|
147
|
+
tryPubSubPublish(topicName, messageObj);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
});
|
|
106
151
|
logger.info(`> '${eventsTopic}' events: `, result);
|
|
107
152
|
});
|
|
108
|
-
return
|
|
153
|
+
return documentRef.set({
|
|
154
|
+
timestamp,
|
|
155
|
+
activeAppsIds,
|
|
156
|
+
listenedEvents,
|
|
157
|
+
});
|
|
109
158
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/storefront",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.59",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce storefront with Astro",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -24,12 +24,13 @@
|
|
|
24
24
|
"@astrojs/partytown": "^1.0.0",
|
|
25
25
|
"@astrojs/prefetch": "^0.0.7",
|
|
26
26
|
"@astrojs/sitemap": "^1.0.0",
|
|
27
|
-
"@astrojs/tailwind": "^1.0.0",
|
|
28
27
|
"@astrojs/vue": "^1.0.0",
|
|
29
28
|
"@cloudcommerce/api": "workspace:*",
|
|
30
29
|
"@picocss/pico": "^1.5.3",
|
|
31
30
|
"astro": "^1.0.6",
|
|
32
31
|
"rollup": "^2.78.1",
|
|
32
|
+
"unocss": "^0.45.12",
|
|
33
|
+
"vite": "^3.0.9",
|
|
33
34
|
"vue": "^3.2.37"
|
|
34
35
|
}
|
|
35
36
|
}
|