@stoker-platform/cli 0.5.12
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/LICENSE.md +102 -0
- package/init-files/.##gitignore## +102 -0
- package/init-files/.devcontainer/devcontainer.json +14 -0
- package/init-files/.env/.env +70 -0
- package/init-files/.eslintrc.cjs +35 -0
- package/init-files/.firebaserc +6 -0
- package/init-files/.prettierignore +86 -0
- package/init-files/.prettierrc +5 -0
- package/init-files/bin/build.js +221 -0
- package/init-files/bin/shim.js +159 -0
- package/init-files/extensions/firestore-send-email.env +7 -0
- package/init-files/external.package.json +4 -0
- package/init-files/firebase-rules/database.rules.json +9 -0
- package/init-files/firebase-rules/firestore.custom.rules +19 -0
- package/init-files/firebase-rules/firestore.indexes.json +0 -0
- package/init-files/firebase-rules/firestore.rules +0 -0
- package/init-files/firebase-rules/storage.rules +0 -0
- package/init-files/firebase.hosting.json +122 -0
- package/init-files/firebase.json +52 -0
- package/init-files/functions/.##gitignore## +14 -0
- package/init-files/functions/.eslintrc.cjs +28 -0
- package/init-files/functions/package.json +46 -0
- package/init-files/functions/prompts/chat.prompt +17 -0
- package/init-files/functions/src/index.ts +457 -0
- package/init-files/functions/tsconfig.dev.json +3 -0
- package/init-files/functions/tsconfig.json +17 -0
- package/init-files/icons/logo-large.png +0 -0
- package/init-files/icons/logo-small.png +0 -0
- package/init-files/ops.js +25 -0
- package/init-files/package.json +53 -0
- package/init-files/project-data.json +5 -0
- package/init-files/remoteconfig.template.json +1 -0
- package/init-files/src/collections/Inbox.ts +444 -0
- package/init-files/src/collections/Outbox.ts +270 -0
- package/init-files/src/collections/Settings.ts +44 -0
- package/init-files/src/collections/Users.ts +138 -0
- package/init-files/src/main.ts +245 -0
- package/init-files/src/utils.ts +3 -0
- package/init-files/src/vite-env.d.ts +1 -0
- package/init-files/test/test.ts +5 -0
- package/init-files/tsconfig.json +23 -0
- package/init-files/vitest.config.ts +9 -0
- package/lib/package.json +45 -0
- package/lib/src/data/exportToBigQuery.js +41 -0
- package/lib/src/data/seedData.js +347 -0
- package/lib/src/deploy/applySchema.js +43 -0
- package/lib/src/deploy/cloud-functions/getFunctionsData.js +18 -0
- package/lib/src/deploy/deployProject.js +116 -0
- package/lib/src/deploy/firestore-export/exportFirestoreData.js +29 -0
- package/lib/src/deploy/firestore-ttl/deployTTLs.js +127 -0
- package/lib/src/deploy/live-update/liveUpdate.js +22 -0
- package/lib/src/deploy/maintenance/activateMaintenanceMode.js +9 -0
- package/lib/src/deploy/maintenance/disableMaintenanceMode.js +9 -0
- package/lib/src/deploy/maintenance/setDeploymentStatus.js +22 -0
- package/lib/src/deploy/rules-indexes/generateFirestoreIndexes.js +23 -0
- package/lib/src/deploy/rules-indexes/generateFirestoreRules.js +35 -0
- package/lib/src/deploy/rules-indexes/generateStorageRules.js +23 -0
- package/lib/src/deploy/schema/generateSchema.js +184 -0
- package/lib/src/deploy/schema/persistSchema.js +14 -0
- package/lib/src/lint/lintSchema.js +1491 -0
- package/lib/src/lint/securityReport.js +223 -0
- package/lib/src/main.js +460 -0
- package/lib/src/migration/firestore/migrateFirestore.js +8 -0
- package/lib/src/migration/firestore/operations/deleteField.js +58 -0
- package/lib/src/migration/migrateAll.js +30 -0
- package/lib/src/ops/auditDenormalized.js +124 -0
- package/lib/src/ops/auditPermissions.js +92 -0
- package/lib/src/ops/auditRelations.js +186 -0
- package/lib/src/ops/explainPreloadQueries.js +65 -0
- package/lib/src/ops/getUser.js +10 -0
- package/lib/src/ops/getUserPermissions.js +19 -0
- package/lib/src/ops/getUserRecord.js +20 -0
- package/lib/src/ops/listProjects.js +8 -0
- package/lib/src/ops/setUserCollection.js +14 -0
- package/lib/src/ops/setUserDocument.js +11 -0
- package/lib/src/ops/setUserRole.js +14 -0
- package/lib/src/project/addProject.js +935 -0
- package/lib/src/project/addRecord.js +9 -0
- package/lib/src/project/addRecordPrompt.js +205 -0
- package/lib/src/project/addTenant.js +59 -0
- package/lib/src/project/buildWebApp.js +10 -0
- package/lib/src/project/customDomain.js +157 -0
- package/lib/src/project/deleteProject.js +51 -0
- package/lib/src/project/deleteRecord.js +11 -0
- package/lib/src/project/deleteTenant.js +49 -0
- package/lib/src/project/getOne.js +25 -0
- package/lib/src/project/getSome.js +28 -0
- package/lib/src/project/initProject.js +16 -0
- package/lib/src/project/prepareEmulatorData.js +125 -0
- package/lib/src/project/setProject.js +13 -0
- package/lib/src/project/startEmulators.js +30 -0
- package/lib/src/project/updateRecord.js +9 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +45 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Source-Available Development License
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 Shopfront International Pty Ltd.
|
|
4
|
+
|
|
5
|
+
This is a source‑available license and not an OSI‑approved open‑source license.
|
|
6
|
+
|
|
7
|
+
## 1. License Grant
|
|
8
|
+
|
|
9
|
+
Subject to the terms of this License, you are granted a **non-exclusive, non-transferable, revocable** license to:
|
|
10
|
+
|
|
11
|
+
- Access the Software.
|
|
12
|
+
- Use the Software **in development environments only**. Development environments include local development, testing, staging, and QA environments that are not accessible to end users.
|
|
13
|
+
|
|
14
|
+
This use is **free of charge**.
|
|
15
|
+
|
|
16
|
+
No other rights are granted except as expressly stated in this License.
|
|
17
|
+
|
|
18
|
+
## 2. Commercial or Production Use
|
|
19
|
+
|
|
20
|
+
**Commercial use or production deployment is strictly prohibited** under this License. This includes, but is not limited to:
|
|
21
|
+
|
|
22
|
+
- Deploying the Software in production environments
|
|
23
|
+
- Using the Software in any revenue-generating product, service, or project
|
|
24
|
+
- Selling, sublicensing, or monetising the Software
|
|
25
|
+
|
|
26
|
+
You may not use the Software, directly or indirectly, to develop, distribute, operate, or enable any product or service that:
|
|
27
|
+
|
|
28
|
+
- #### Competes with the Software
|
|
29
|
+
|
|
30
|
+
By functioning as a headless CMS, application framework, developer platform, or substantially similar system.
|
|
31
|
+
|
|
32
|
+
- #### Replicates Core Functionality
|
|
33
|
+
|
|
34
|
+
Copies or substantially mirrors the Software’s architecture, workflows, abstractions, or core features.
|
|
35
|
+
|
|
36
|
+
- #### Offers the Software as a Service
|
|
37
|
+
|
|
38
|
+
Provides the Software itself or its functionality to third parties as a managed service, hosted platform, API, or marketplace.
|
|
39
|
+
|
|
40
|
+
- #### Rebrands or White-Labels the Software
|
|
41
|
+
|
|
42
|
+
Offers the Software itself under a different name, branding, or identity.
|
|
43
|
+
|
|
44
|
+
- #### Creates Derived Frameworks or Tooling
|
|
45
|
+
|
|
46
|
+
Distributes frameworks, starter kits, templates, scaffolding, or developer toolkits substantially derived from the Software.
|
|
47
|
+
|
|
48
|
+
- #### Competitive Analysis and Cloning
|
|
49
|
+
|
|
50
|
+
Uses the Software mainly to analyse, benchmark, reverse engineer, or replicate it for a competing product or service.
|
|
51
|
+
|
|
52
|
+
- #### Artificial Intelligence and Machine Learning
|
|
53
|
+
Uses the Software itself to train, fine-tune, or improve artificial intelligence or machine learning models.
|
|
54
|
+
|
|
55
|
+
To use the Software commercially or in production, you must obtain a Commercial License from the Licensor. Contact info@getoutpost.com for licensing information.
|
|
56
|
+
|
|
57
|
+
## 3. Contributions
|
|
58
|
+
|
|
59
|
+
You may fork or modify the Software for contribution purposes.
|
|
60
|
+
|
|
61
|
+
You may submit issues, bug reports, feature requests, and pull requests through public channels (such as GitHub) as a means of contributing to the Software. Modifications may not be otherwise shared or distributed except through such official contribution channels.
|
|
62
|
+
|
|
63
|
+
By submitting contributions, suggestions, or modifications to the Licensor in connection with the Software, you grant the Licensor a perpetual, worldwide, royalty-free, non-exclusive, fully transferable, and sublicensable license to use, modify, distribute, and otherwise exploit such contributions as part of the Software. You retain ownership of your contributions but grant these rights to enable the Licensor to incorporate and distribute your contributions as part of the Software.
|
|
64
|
+
|
|
65
|
+
## 4. Ownership
|
|
66
|
+
|
|
67
|
+
The Software is **licensed, not sold**. All rights not expressly granted herein are retained by the Licensor.
|
|
68
|
+
|
|
69
|
+
All trademarks, service marks, and logos associated with the Software are the property of the Licensor and may not be used without permission.
|
|
70
|
+
|
|
71
|
+
## 5. Alpha Mode
|
|
72
|
+
|
|
73
|
+
- The Software may be provided in alpha or pre-release form. Features, functionality, and data handling may change without notice.
|
|
74
|
+
- By using the Software in alpha, you acknowledge it may contain bugs, errors, or incomplete functionality.
|
|
75
|
+
- The Licensor makes no commitment to maintain backward compatibility or preserve data formats during the alpha period.
|
|
76
|
+
- Alpha releases may be discontinued or replaced without prior notice.
|
|
77
|
+
- You are responsible for backing up your data and testing compatibility before upgrading.
|
|
78
|
+
|
|
79
|
+
## 6. Limited Warranty / Liability
|
|
80
|
+
|
|
81
|
+
- To the extent permitted by law, the Software is provided **"AS IS"**, without warranties of any kind, express or implied, including but not limited to warranties of merchantability, fitness for a particular purpose, or non-infringement.
|
|
82
|
+
- Licensor is not liable for any damages arising from use or inability to use the Software, to the maximum extent permitted by law.
|
|
83
|
+
- Nothing in this License excludes rights or remedies that cannot be waived under applicable law.
|
|
84
|
+
|
|
85
|
+
## 7. Termination
|
|
86
|
+
|
|
87
|
+
This License automatically terminates if you fail to comply with any term or condition. In this case, you must immediately stop using the Software.
|
|
88
|
+
|
|
89
|
+
**The licensor may terminate this license at any time**, for any reason, when 60 days notice is given on the Licensor's website at https://stoker-website.web.app. In this case, you will need to purchase a commerical license to continue using the Software.
|
|
90
|
+
|
|
91
|
+
The Licensor reserves the right to pursue legal remedies for any violation, including injunctive relief.
|
|
92
|
+
|
|
93
|
+
## 8. Governing Law
|
|
94
|
+
|
|
95
|
+
This License is governed by and shall be construed under the laws of Victoria, Australia, without regard to conflict-of-law principles.
|
|
96
|
+
|
|
97
|
+
Any disputes arising under this License shall be resolved exclusively in the courts of Victoria, Australia.
|
|
98
|
+
|
|
99
|
+
## 9. Commercial License
|
|
100
|
+
|
|
101
|
+
For commercial use or production deployment, a Commercial License Agreement must be obtained.
|
|
102
|
+
Please contact info@getoutpost.com for details.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
firebase-debug.log*
|
|
10
|
+
firebase-debug.*.log*
|
|
11
|
+
|
|
12
|
+
# Firebase cache
|
|
13
|
+
.firebase/
|
|
14
|
+
|
|
15
|
+
# Firebase config
|
|
16
|
+
|
|
17
|
+
# Uncomment this if you'd like others to create their own Firebase project.
|
|
18
|
+
# For a team working on the same Firebase project(s), it is recommended to leave
|
|
19
|
+
# it commented so all members can deploy to the same project(s) in .firebaserc.
|
|
20
|
+
# .firebaserc
|
|
21
|
+
|
|
22
|
+
# Runtime data
|
|
23
|
+
pids
|
|
24
|
+
*.pid
|
|
25
|
+
*.seed
|
|
26
|
+
*.pid.lock
|
|
27
|
+
|
|
28
|
+
# Editor directories and files
|
|
29
|
+
.vscode/*
|
|
30
|
+
!.vscode/extensions.json
|
|
31
|
+
.idea
|
|
32
|
+
.DS_Store
|
|
33
|
+
*.suo
|
|
34
|
+
*.ntvs*
|
|
35
|
+
*.njsproj
|
|
36
|
+
*.sln
|
|
37
|
+
*.sw?
|
|
38
|
+
|
|
39
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
40
|
+
lib-cov
|
|
41
|
+
|
|
42
|
+
# Coverage directory used by tools like istanbul
|
|
43
|
+
coverage
|
|
44
|
+
|
|
45
|
+
# nyc test coverage
|
|
46
|
+
.nyc_output
|
|
47
|
+
|
|
48
|
+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
49
|
+
.grunt
|
|
50
|
+
|
|
51
|
+
# Bower dependency directory (https://bower.io/)
|
|
52
|
+
bower_components
|
|
53
|
+
|
|
54
|
+
# node-waf configuration
|
|
55
|
+
.lock-wscript
|
|
56
|
+
|
|
57
|
+
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
58
|
+
build/Release
|
|
59
|
+
|
|
60
|
+
# Dependency directories
|
|
61
|
+
node_modules/
|
|
62
|
+
|
|
63
|
+
# Optional npm cache directory
|
|
64
|
+
.npm
|
|
65
|
+
|
|
66
|
+
# npm config file
|
|
67
|
+
.npmrc
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Optional eslint cache
|
|
71
|
+
.eslintcache
|
|
72
|
+
|
|
73
|
+
# Optional REPL history
|
|
74
|
+
.node_repl_history
|
|
75
|
+
|
|
76
|
+
# Output of 'npm pack'
|
|
77
|
+
*.tgz
|
|
78
|
+
|
|
79
|
+
# Yarn Integrity file
|
|
80
|
+
.yarn-integrity
|
|
81
|
+
|
|
82
|
+
# Turborepo configuration
|
|
83
|
+
.turbo
|
|
84
|
+
|
|
85
|
+
# Build directories
|
|
86
|
+
lib
|
|
87
|
+
dist
|
|
88
|
+
dist-ssr
|
|
89
|
+
*.local
|
|
90
|
+
|
|
91
|
+
# Dotenv variables
|
|
92
|
+
.env
|
|
93
|
+
.env.*
|
|
94
|
+
|
|
95
|
+
# Firebase GenKit directory
|
|
96
|
+
.genkit
|
|
97
|
+
|
|
98
|
+
# Firebase emulator data
|
|
99
|
+
firebase-emulator-data/*
|
|
100
|
+
|
|
101
|
+
# Web app directory
|
|
102
|
+
web-app
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"image": "mcr.microsoft.com/devcontainers/universal:2",
|
|
3
|
+
"features": {
|
|
4
|
+
"ghcr.io/dhoeric/features/google-cloud-cli:1": {
|
|
5
|
+
"version": "latest"
|
|
6
|
+
},
|
|
7
|
+
"ghcr.io/devcontainers-contrib/features/firebase-cli:2": {
|
|
8
|
+
"version": "latest"
|
|
9
|
+
},
|
|
10
|
+
"ghcr.io/devcontainers-contrib/features/typescript:2": {
|
|
11
|
+
"version": "latest"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
ADMIN_EMAIL=""
|
|
2
|
+
ADMIN_SMS=""
|
|
3
|
+
|
|
4
|
+
GCP_BILLING_ACCOUNT=""
|
|
5
|
+
|
|
6
|
+
GCP_ORGANIZATION=""
|
|
7
|
+
GCP_FOLDER=""
|
|
8
|
+
|
|
9
|
+
FB_GOOGLE_ANALYTICS_ACCOUNT_ID=""
|
|
10
|
+
|
|
11
|
+
FB_FIRESTORE_REGION="australia-southeast2"
|
|
12
|
+
FB_FIRESTORE_ENABLE_PITR=true
|
|
13
|
+
FB_FIRESTORE_BACKUP_RECURRENCE="daily"
|
|
14
|
+
FB_FIRESTORE_BACKUP_RETENTION="7d"
|
|
15
|
+
|
|
16
|
+
FB_DATABASE_REGION="asia-southeast1"
|
|
17
|
+
|
|
18
|
+
FB_STORAGE_REGION="australia-southeast2"
|
|
19
|
+
FB_STORAGE_ENABLE_VERSIONING=true
|
|
20
|
+
FB_STORAGE_SOFT_DELETE_DURATION="30d"
|
|
21
|
+
|
|
22
|
+
FB_AUTH_PASSWORD_POLICY='{
|
|
23
|
+
"containsLowercaseCharacter": false,
|
|
24
|
+
"containsUppercaseCharacter": false,
|
|
25
|
+
"containsNumericCharacter": false,
|
|
26
|
+
"containsNonAlphanumericCharacter": false,
|
|
27
|
+
"minPasswordLength": 12,
|
|
28
|
+
"maxPasswordLength": 128
|
|
29
|
+
}'
|
|
30
|
+
FB_AUTH_PASSWORD_POLICY_UPGRADE=false
|
|
31
|
+
|
|
32
|
+
FB_FUNCTIONS_REGION="australia-southeast2"
|
|
33
|
+
FB_FUNCTIONS_V1_REGION="australia-southeast1"
|
|
34
|
+
FB_FUNCTIONS_MEMORY="1GiB"
|
|
35
|
+
FB_FUNCTIONS_TIMEOUT=540
|
|
36
|
+
FB_FUNCTIONS_MAX_INSTANCES=100
|
|
37
|
+
FB_FUNCTIONS_MIN_INSTANCES=0
|
|
38
|
+
FB_FUNCTIONS_CPU=1
|
|
39
|
+
FB_FUNCTIONS_CONCURRENCY=80
|
|
40
|
+
FB_FUNCTIONS_CONSUME_APP_CHECK_TOKEN=false
|
|
41
|
+
|
|
42
|
+
FB_HOSTING_ENABLE_CLOUD_LOGGING=true
|
|
43
|
+
FB_HOSTING_MAX_VERSIONS=3
|
|
44
|
+
|
|
45
|
+
FB_ENABLE_APP_CHECK=true
|
|
46
|
+
FB_APP_CHECK_TOKEN_TTL="3600s"
|
|
47
|
+
|
|
48
|
+
FB_AI_REGION="us-west1"
|
|
49
|
+
|
|
50
|
+
MAIL_REGION="asia-northeast1"
|
|
51
|
+
MAIL_SENDER=""
|
|
52
|
+
MAIL_SMTP_CONNECTION_URI=""
|
|
53
|
+
MAIL_SMTP_PASSWORD=""
|
|
54
|
+
|
|
55
|
+
TWILIO_ACCOUNT_SID=""
|
|
56
|
+
TWILIO_AUTH_TOKEN=""
|
|
57
|
+
TWILIO_PHONE_NUMBER=""
|
|
58
|
+
|
|
59
|
+
ALGOLIA_ID=""
|
|
60
|
+
ALGOLIA_ADMIN_KEY=""
|
|
61
|
+
|
|
62
|
+
SENTRY_DSN=""
|
|
63
|
+
|
|
64
|
+
FULLCALENDAR_KEY=""
|
|
65
|
+
|
|
66
|
+
EXTERNAL_SECRETS='{}'
|
|
67
|
+
|
|
68
|
+
URL_FIRESTORE_INDEXES="https://australia-southeast2-stoker-backend-prod-v1.cloudfunctions.net/stoker-getfirestoreindexes"
|
|
69
|
+
URL_FIRESTORE_RULES="https://australia-southeast2-stoker-backend-prod-v1.cloudfunctions.net/stoker-getfirestorerules"
|
|
70
|
+
URL_STORAGE_RULES="https://australia-southeast2-stoker-backend-prod-v1.cloudfunctions.net/stoker-getstoragerules"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
es6: true,
|
|
4
|
+
node: true,
|
|
5
|
+
},
|
|
6
|
+
extends: [
|
|
7
|
+
"eslint:recommended",
|
|
8
|
+
"plugin:import/errors",
|
|
9
|
+
"plugin:import/warnings",
|
|
10
|
+
"plugin:import/typescript",
|
|
11
|
+
"plugin:@typescript-eslint/recommended",
|
|
12
|
+
"plugin:security/recommended-legacy",
|
|
13
|
+
"prettier",
|
|
14
|
+
],
|
|
15
|
+
parser: "@typescript-eslint/parser",
|
|
16
|
+
parserOptions: {
|
|
17
|
+
project: ["tsconfig.json"],
|
|
18
|
+
sourceType: "module",
|
|
19
|
+
},
|
|
20
|
+
ignorePatterns: [
|
|
21
|
+
"/lib/**/*",
|
|
22
|
+
"/dist/**/*",
|
|
23
|
+
"bin/**/*",
|
|
24
|
+
"test/**/*",
|
|
25
|
+
"vitest.config.ts",
|
|
26
|
+
"/functions",
|
|
27
|
+
"/web-app",
|
|
28
|
+
"ops.js",
|
|
29
|
+
],
|
|
30
|
+
plugins: ["@typescript-eslint", "import"],
|
|
31
|
+
rules: {
|
|
32
|
+
"import/no-unresolved": 0,
|
|
33
|
+
"prefer-rest-params": 0,
|
|
34
|
+
},
|
|
35
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
firebase-debug.log*
|
|
10
|
+
firebase-debug.*.log*
|
|
11
|
+
|
|
12
|
+
# Firebase cache
|
|
13
|
+
.firebase/
|
|
14
|
+
|
|
15
|
+
# Runtime data
|
|
16
|
+
pids
|
|
17
|
+
*.pid
|
|
18
|
+
*.seed
|
|
19
|
+
*.pid.lock
|
|
20
|
+
|
|
21
|
+
# Editor directories and files
|
|
22
|
+
.vscode/*
|
|
23
|
+
!.vscode/extensions.json
|
|
24
|
+
.idea
|
|
25
|
+
.DS_Store
|
|
26
|
+
*.suo
|
|
27
|
+
*.ntvs*
|
|
28
|
+
*.njsproj
|
|
29
|
+
*.sln
|
|
30
|
+
*.sw?
|
|
31
|
+
|
|
32
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
33
|
+
lib-cov
|
|
34
|
+
|
|
35
|
+
# Coverage directory used by tools like istanbul
|
|
36
|
+
coverage
|
|
37
|
+
|
|
38
|
+
# nyc test coverage
|
|
39
|
+
.nyc_output
|
|
40
|
+
|
|
41
|
+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
|
42
|
+
.grunt
|
|
43
|
+
|
|
44
|
+
# Bower dependency directory (https://bower.io/)
|
|
45
|
+
bower_components
|
|
46
|
+
|
|
47
|
+
# node-waf configuration
|
|
48
|
+
.lock-wscript
|
|
49
|
+
|
|
50
|
+
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
|
51
|
+
build/Release
|
|
52
|
+
|
|
53
|
+
# Optional npm cache directory
|
|
54
|
+
.npm
|
|
55
|
+
|
|
56
|
+
# Optional eslint cache
|
|
57
|
+
.eslintcache
|
|
58
|
+
|
|
59
|
+
# Optional REPL history
|
|
60
|
+
.node_repl_history
|
|
61
|
+
|
|
62
|
+
# Output of 'npm pack'
|
|
63
|
+
*.tgz
|
|
64
|
+
|
|
65
|
+
# Yarn Integrity file
|
|
66
|
+
.yarn-integrity
|
|
67
|
+
|
|
68
|
+
# Turborepo configuration
|
|
69
|
+
.turbo
|
|
70
|
+
|
|
71
|
+
# Build directories
|
|
72
|
+
lib
|
|
73
|
+
dist
|
|
74
|
+
dist-ssr
|
|
75
|
+
*.local
|
|
76
|
+
|
|
77
|
+
# Firebase GenKit directory
|
|
78
|
+
.genkit
|
|
79
|
+
|
|
80
|
+
# Firebase directories
|
|
81
|
+
|
|
82
|
+
firebase-rules/
|
|
83
|
+
functions/src/
|
|
84
|
+
functions/.eslintrc.cjs
|
|
85
|
+
|
|
86
|
+
package-lock.json
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
#!/usr/bin/env -S node --no-warnings
|
|
2
|
+
|
|
3
|
+
import { fileURLToPath } from "url"
|
|
4
|
+
import { dirname, join } from "path"
|
|
5
|
+
import { readFile, writeFile, readdir, mkdir, copyFile } from "fs/promises"
|
|
6
|
+
import { existsSync, cpSync, rmSync } from "fs"
|
|
7
|
+
import dotenv from "dotenv"
|
|
8
|
+
import { runChildProcess } from "@stoker-platform/node-client"
|
|
9
|
+
|
|
10
|
+
const envDir = join(process.cwd(), ".env")
|
|
11
|
+
const projectEnvFile = join(envDir, `.env.project.${process.env.GCP_PROJECT}`)
|
|
12
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
13
|
+
if (existsSync(projectEnvFile)) {
|
|
14
|
+
dotenv.config({ path: projectEnvFile, quiet: true })
|
|
15
|
+
} else {
|
|
16
|
+
dotenv.config({ path: join(process.cwd(), ".env", ".env"), quiet: true })
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
21
|
+
const __dirname = dirname(__filename)
|
|
22
|
+
|
|
23
|
+
// Remove CSS imports from all JS files in lib directory
|
|
24
|
+
|
|
25
|
+
async function processFile(filePath) {
|
|
26
|
+
try {
|
|
27
|
+
const content = await readFile(filePath, "utf8")
|
|
28
|
+
const lines = content.split("\n")
|
|
29
|
+
const filteredLines = lines.filter((line) => {
|
|
30
|
+
const trimmed = line.trim()
|
|
31
|
+
// Match: import "./something.css" or import './something.css'
|
|
32
|
+
if (/^import\s+["']\.\/.*\.css["'];?\s*$/.test(trimmed)) {
|
|
33
|
+
return false
|
|
34
|
+
}
|
|
35
|
+
// Match: import "something.css" or import 'something.css' (absolute imports)
|
|
36
|
+
if (/^import\s+["'].*\.css["'];?\s*$/.test(trimmed)) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
return true
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
const newContent = filteredLines.join("\n")
|
|
43
|
+
if (newContent !== content) {
|
|
44
|
+
await writeFile(filePath, newContent, "utf8")
|
|
45
|
+
console.log(`Removed CSS imports from: ${filePath}`)
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(`Error processing ${filePath}:`, error.message)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function walkDirectory(dir) {
|
|
53
|
+
try {
|
|
54
|
+
const entries = await readdir(dir, { withFileTypes: true })
|
|
55
|
+
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
const fullPath = join(dir, entry.name)
|
|
58
|
+
|
|
59
|
+
if (entry.isDirectory()) {
|
|
60
|
+
await walkDirectory(fullPath)
|
|
61
|
+
} else if (entry.isFile() && entry.name.endsWith(".js")) {
|
|
62
|
+
await processFile(fullPath)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
if (error.code !== "ENOENT") {
|
|
67
|
+
console.error(`Error walking directory ${dir}:`, error.message)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
async function removeCSSImports() {
|
|
73
|
+
const libDir = join(__dirname, "..", "lib")
|
|
74
|
+
await walkDirectory(libDir)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await removeCSSImports().catch((error) => {
|
|
78
|
+
console.error("Error:", error)
|
|
79
|
+
process.exit(1)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
// Set up Firebase Extension files
|
|
83
|
+
|
|
84
|
+
let envFile
|
|
85
|
+
if (existsSync(projectEnvFile)) {
|
|
86
|
+
envFile = await readFile(projectEnvFile, "utf8")
|
|
87
|
+
} else {
|
|
88
|
+
envFile = await readFile(join(__dirname, "..", ".env", ".env"), "utf8")
|
|
89
|
+
}
|
|
90
|
+
const envFileLines = envFile.split("\n")
|
|
91
|
+
const databaseRegion = envFileLines.find((line) => line.startsWith("FB_FIRESTORE_REGION="))
|
|
92
|
+
|
|
93
|
+
const mailRegion = envFileLines.find((line) => line.startsWith("MAIL_REGION="))
|
|
94
|
+
const mailSender = envFileLines.find((line) => line.startsWith("MAIL_SENDER="))
|
|
95
|
+
const mailSmtpConnectionUri = envFileLines.find((line) => line.startsWith("MAIL_SMTP_CONNECTION_URI="))
|
|
96
|
+
|
|
97
|
+
const extensionEnvFile = await readFile(join(__dirname, "..", "extensions", "firestore-send-email.env"), "utf8")
|
|
98
|
+
const extensionEnvFileLines = extensionEnvFile.split("\n")
|
|
99
|
+
const linesToRemove = [
|
|
100
|
+
"EVENTARC_CHANNEL=",
|
|
101
|
+
"DEFAULT_FROM=",
|
|
102
|
+
"DEFAULT_REPLY_TO=",
|
|
103
|
+
"SMTP_CONNECTION_URI=",
|
|
104
|
+
"firebaseextensions.v1beta.function/location=",
|
|
105
|
+
"DATABASE_REGION=",
|
|
106
|
+
]
|
|
107
|
+
const filteredLines = extensionEnvFileLines.filter(
|
|
108
|
+
(line) => !linesToRemove.some((removeStr) => line.startsWith(removeStr)),
|
|
109
|
+
)
|
|
110
|
+
filteredLines.push(
|
|
111
|
+
`EVENTARC_CHANNEL=projects/\${param:PROJECT_ID}/locations/${mailRegion.split("=")[1].replace(/^"|"$/g, "")}/channels/firebase`,
|
|
112
|
+
)
|
|
113
|
+
filteredLines.push(`firebaseextensions.v1beta.function/location=${process.env.FB_FUNCTIONS_REGION}`)
|
|
114
|
+
filteredLines.push(`DEFAULT_FROM=${mailSender.split("=")[1].replace(/^"|"$/g, "")}`)
|
|
115
|
+
filteredLines.push(`DEFAULT_REPLY_TO=${mailSender.split("=")[1].replace(/^"|"$/g, "")}`)
|
|
116
|
+
filteredLines.push(`SMTP_CONNECTION_URI=${mailSmtpConnectionUri.split("=")[1].replace(/^"|"$/g, "")}`)
|
|
117
|
+
filteredLines.push(`DATABASE_REGION=${databaseRegion.split("=")[1].replace(/^"|"$/g, "")}`)
|
|
118
|
+
await writeFile(join(__dirname, "..", "extensions", "firestore-send-email.env"), filteredLines.join("\n"))
|
|
119
|
+
|
|
120
|
+
// Update dependencies according to external.package.json
|
|
121
|
+
|
|
122
|
+
const updateDependencies = async (packageJsonPath, externalDeps) => {
|
|
123
|
+
const packageJsonRaw = await readFile(packageJsonPath, "utf8")
|
|
124
|
+
const packageJson = JSON.parse(packageJsonRaw)
|
|
125
|
+
|
|
126
|
+
const dependencies = packageJson.dependencies || {}
|
|
127
|
+
const previouslyManaged = packageJson.stokerExternalPackages || {}
|
|
128
|
+
|
|
129
|
+
let changed = false
|
|
130
|
+
|
|
131
|
+
for (const managedName of Object.keys(previouslyManaged)) {
|
|
132
|
+
if (!Object.prototype.hasOwnProperty.call(externalDeps, managedName)) {
|
|
133
|
+
if (Object.prototype.hasOwnProperty.call(dependencies, managedName)) {
|
|
134
|
+
delete dependencies[managedName]
|
|
135
|
+
changed = true
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
for (const [depName, depVersion] of Object.entries(externalDeps)) {
|
|
141
|
+
if (dependencies[depName] !== depVersion) {
|
|
142
|
+
dependencies[depName] = depVersion
|
|
143
|
+
changed = true
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
packageJson.dependencies = dependencies
|
|
148
|
+
packageJson.stokerExternalPackages = externalDeps
|
|
149
|
+
|
|
150
|
+
if (changed || JSON.stringify(previouslyManaged) !== JSON.stringify(externalDeps)) {
|
|
151
|
+
await writeFile(packageJsonPath, JSON.stringify(packageJson, null, 4) + "\n")
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return changed
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const externalPackagesPath = join(process.cwd(), "external.package.json")
|
|
158
|
+
if (existsSync(externalPackagesPath)) {
|
|
159
|
+
const externalRaw = await readFile(externalPackagesPath, "utf8")
|
|
160
|
+
const external = JSON.parse(externalRaw)
|
|
161
|
+
const serverDeps = external.server || {}
|
|
162
|
+
const webDeps = external.web || {}
|
|
163
|
+
|
|
164
|
+
const appDir = join(process.cwd())
|
|
165
|
+
const functionsDir = join(process.cwd(), "functions")
|
|
166
|
+
|
|
167
|
+
const appPackageJson = join(appDir, "package.json")
|
|
168
|
+
const functionsPackageJson = join(functionsDir, "package.json")
|
|
169
|
+
|
|
170
|
+
const appChanged = await updateDependencies(appPackageJson, { ...serverDeps, ...webDeps })
|
|
171
|
+
const functionsChanged = await updateDependencies(functionsPackageJson, serverDeps)
|
|
172
|
+
|
|
173
|
+
if (appChanged) {
|
|
174
|
+
await runChildProcess("npm", ["install", "--no-audit", "--no-fund"], appDir)
|
|
175
|
+
}
|
|
176
|
+
if (functionsChanged) {
|
|
177
|
+
await runChildProcess("npm", ["install", "--no-audit", "--no-fund"], functionsDir)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Create functions .env file with filtered environment variables
|
|
182
|
+
|
|
183
|
+
const functionsEnvPath = join(process.cwd(), "functions", ".env")
|
|
184
|
+
const defaultEnvFile = join(envDir, ".env")
|
|
185
|
+
const projectSpecificEnvFile = join(envDir, `.env.${process.env.GCP_PROJECT}`)
|
|
186
|
+
|
|
187
|
+
let envContent = ""
|
|
188
|
+
const envPattern = /^(FB_FUNCTIONS_|FB_AI_REGION|STOKER_|ADMIN_)/
|
|
189
|
+
|
|
190
|
+
if (existsSync(projectEnvFile)) {
|
|
191
|
+
const projectEnvContent = await readFile(projectEnvFile, "utf8")
|
|
192
|
+
const projectSpecificContent = existsSync(projectSpecificEnvFile)
|
|
193
|
+
? await readFile(projectSpecificEnvFile, "utf8")
|
|
194
|
+
: ""
|
|
195
|
+
|
|
196
|
+
const allLines = [...projectEnvContent.split("\n"), ...projectSpecificContent.split("\n")]
|
|
197
|
+
const filteredLines = allLines.filter((line) => envPattern.test(line.trim()))
|
|
198
|
+
envContent = filteredLines.join("\n")
|
|
199
|
+
} else {
|
|
200
|
+
const defaultContent = existsSync(defaultEnvFile) ? await readFile(defaultEnvFile, "utf8") : ""
|
|
201
|
+
const projectSpecificContent = existsSync(projectSpecificEnvFile)
|
|
202
|
+
? await readFile(projectSpecificEnvFile, "utf8")
|
|
203
|
+
: ""
|
|
204
|
+
|
|
205
|
+
const allLines = [...defaultContent.split("\n"), ...projectSpecificContent.split("\n")]
|
|
206
|
+
const filteredLines = allLines.filter((line) => envPattern.test(line.trim()))
|
|
207
|
+
envContent = filteredLines.join("\n")
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
await writeFile(functionsEnvPath, envContent, "utf8")
|
|
211
|
+
|
|
212
|
+
// Copy source files to functions directory
|
|
213
|
+
|
|
214
|
+
const systemCustom = join(process.cwd(), "functions", "src", "system-custom")
|
|
215
|
+
if (existsSync(systemCustom)) {
|
|
216
|
+
rmSync(systemCustom, { recursive: true })
|
|
217
|
+
}
|
|
218
|
+
cpSync(join(process.cwd(), "src"), systemCustom, { recursive: true })
|
|
219
|
+
} catch (error) {
|
|
220
|
+
throw new Error(error)
|
|
221
|
+
}
|