├── .eslintrc
├── .gitignore
├── .jshintrc
├── .profile
├── .travis.yml
├── LICENSE
├── Procfile
├── README.md
├── app.json
├── assets
└── deployments.sql
├── dist
└── assets
│ ├── css
│ └── main.css
│ ├── favicons
│ ├── android-icon-144x144.png
│ ├── android-icon-192x192.png
│ ├── android-icon-36x36.png
│ ├── android-icon-48x48.png
│ ├── android-icon-72x72.png
│ ├── android-icon-96x96.png
│ ├── apple-icon-114x114.png
│ ├── apple-icon-120x120.png
│ ├── apple-icon-144x144.png
│ ├── apple-icon-152x152.png
│ ├── apple-icon-180x180.png
│ ├── apple-icon-57x57.png
│ ├── apple-icon-60x60.png
│ ├── apple-icon-72x72.png
│ ├── apple-icon-76x76.png
│ ├── apple-icon-precomposed.png
│ ├── apple-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon-96x96.png
│ ├── favicon.ico
│ ├── manifest.json
│ ├── ms-icon-144x144.png
│ ├── ms-icon-150x150.png
│ ├── ms-icon-310x310.png
│ └── ms-icon-70x70.png
│ ├── fonts
│ ├── License-for-font.txt
│ ├── SalesforceSans-Bold.ttf
│ ├── SalesforceSans-BoldItalic.ttf
│ ├── SalesforceSans-Book.ttf
│ ├── SalesforceSans-Italic.ttf
│ ├── SalesforceSans-Light.ttf
│ ├── SalesforceSans-LightItalic.ttf
│ ├── SalesforceSans-Regular.ttf
│ ├── SalesforceSans-Semibold.ttf
│ ├── SalesforceSans-Thin.ttf
│ ├── SalesforceSans-ThinItalic.ttf
│ └── webfonts
│ │ ├── SalesforceSans-Bold.woff
│ │ ├── SalesforceSans-Bold.woff2
│ │ ├── SalesforceSans-BoldItalic.woff
│ │ ├── SalesforceSans-BoldItalic.woff2
│ │ ├── SalesforceSans-Italic.woff
│ │ ├── SalesforceSans-Italic.woff2
│ │ ├── SalesforceSans-Light.woff
│ │ ├── SalesforceSans-Light.woff2
│ │ ├── SalesforceSans-LightItalic.woff
│ │ ├── SalesforceSans-LightItalic.woff2
│ │ ├── SalesforceSans-Regular.woff
│ │ ├── SalesforceSans-Regular.woff2
│ │ ├── SalesforceSans-Thin.woff
│ │ ├── SalesforceSans-Thin.woff2
│ │ ├── SalesforceSans-ThinItalic.woff
│ │ └── SalesforceSans-ThinItalic.woff2
│ └── images
│ ├── DeployToSFDX.svg
│ ├── launch.png
│ ├── loader.gif
│ └── salesforce_cloud.png
├── lib
├── apis.js
├── commands.js
├── postgres.js
├── steps.js
└── web.js
├── package.json
├── scripts
├── choose.js
├── deploy.js
├── deploying.js
└── js-yaml.min.js
├── src
├── assets
│ ├── favicons
│ │ ├── android-icon-144x144.png
│ │ ├── android-icon-192x192.png
│ │ ├── android-icon-36x36.png
│ │ ├── android-icon-48x48.png
│ │ ├── android-icon-72x72.png
│ │ ├── android-icon-96x96.png
│ │ ├── apple-icon-114x114.png
│ │ ├── apple-icon-120x120.png
│ │ ├── apple-icon-144x144.png
│ │ ├── apple-icon-152x152.png
│ │ ├── apple-icon-180x180.png
│ │ ├── apple-icon-57x57.png
│ │ ├── apple-icon-60x60.png
│ │ ├── apple-icon-72x72.png
│ │ ├── apple-icon-76x76.png
│ │ ├── apple-icon-precomposed.png
│ │ ├── apple-icon.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon-96x96.png
│ │ ├── favicon.ico
│ │ ├── manifest.json
│ │ ├── ms-icon-144x144.png
│ │ ├── ms-icon-150x150.png
│ │ ├── ms-icon-310x310.png
│ │ └── ms-icon-70x70.png
│ └── images
│ │ ├── DeployToSFDX.svg
│ │ ├── launch.png
│ │ ├── loader.gif
│ │ └── salesforce_cloud.png
└── scss
│ └── main.scss
├── views
├── pages
│ ├── about.ejs
│ ├── choose.ejs
│ ├── deploy.ejs
│ ├── deploying.ejs
│ ├── error.ejs
│ ├── index.ejs
│ ├── notdevhub.ejs
│ └── repo.ejs
└── partials
│ ├── actions.ejs
│ ├── footer.ejs
│ └── head.ejs
├── web.js
└── worker.js
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb-base",
3 | "parserOptions": {
4 | "ecmaVersion": 6
5 | },
6 | "env": {
7 | "node": true,
8 | "es6": true
9 | },
10 | "rules" : {
11 | "arrow-body-style": ["error", "as-needed"],
12 | "no-alert": 2,
13 | "no-array-constructor": 2,
14 | "no-bitwise": 0,
15 | "no-caller": 0,
16 | "no-catch-shadow": 2,
17 | "no-comma-dangle": 0,
18 | "no-cond-assign": 2,
19 | "no-console": 0,
20 | "no-constant-condition": 2,
21 | "no-control-regex": 2,
22 | "no-debugger": 2,
23 | "no-delete-var": 2,
24 | "no-div-regex": 0,
25 | "no-dupe-keys": 2,
26 | "no-dupe-args": 2,
27 | "no-duplicate-case": 2,
28 | "no-else-return": 0,
29 | "no-empty": 2,
30 | "no-empty-character-class": 2,
31 | "no-eq-null": 0,
32 | "no-eval": 2,
33 | "no-ex-assign": 2,
34 | "no-extend-native": 0,
35 | "no-extra-bind": 2,
36 | "no-extra-boolean-cast": 2,
37 | "no-extra-parens": 0,
38 | "no-extra-semi": 2,
39 | "no-fallthrough": 2,
40 | "no-floating-decimal": 0,
41 | "no-func-assign": 2,
42 | "no-implied-eval": 2,
43 | "no-inline-comments": 0,
44 | "no-inner-declarations": [2, "functions"],
45 | "no-invalid-regexp": 2,
46 | "no-irregular-whitespace": 2,
47 | "no-iterator": 2,
48 | "no-label-var": 2,
49 | "no-labels": 2,
50 | "no-lone-blocks": 2,
51 | "no-lonely-if": 0,
52 | "no-loop-func": 2,
53 | "no-mixed-requires": [0, false],
54 | "no-mixed-spaces-and-tabs": 0,
55 | "no-multi-spaces": 0,
56 | "no-multi-str": 2,
57 | "no-multiple-empty-lines": 0,
58 | "no-native-reassign": 2,
59 | "no-negated-in-lhs": 2,
60 | "no-nested-ternary": 0,
61 | "no-new": 2,
62 | "no-new-func": 0,
63 | "no-new-object": 2,
64 | "no-new-require": 0,
65 | "no-new-wrappers": 2,
66 | "no-obj-calls": 2,
67 | "no-octal": 2,
68 | "no-octal-escape": 2,
69 | "no-param-reassign": 0,
70 | "no-path-concat": 0,
71 | "no-plusplus": 0,
72 | "no-process-env": 0,
73 | "no-process-exit": 2,
74 | "no-proto": 1,
75 | "no-redeclare": 2,
76 | "no-regex-spaces": 2,
77 | "no-reserved-keys": 0,
78 | "no-restricted-modules": 0,
79 | "no-return-assign": 2,
80 | "no-script-url": 2,
81 | "no-self-compare": 0,
82 | "no-sequences": 2,
83 | "no-shadow": 2,
84 | "no-shadow-restricted-names": 2,
85 | "no-space-before-semi": 0,
86 | "no-spaced-func": 2,
87 | "no-sparse-arrays": 2,
88 | "no-sync": 0,
89 | "no-tabs": 2,
90 | "no-ternary": 0,
91 | "no-trailing-spaces": 0,
92 | "no-throw-literal": 0,
93 | "no-undef": 2,
94 | "no-undef-init": 0,
95 | "no-undefined": 0,
96 | "no-underscore-dangle": 0,
97 | "no-unreachable": 2,
98 | "no-unused-expressions": 0,
99 | "no-unused-vars": [2, {"vars": "local", "args": "after-used"}],
100 | "no-use-before-define": 1,
101 | "no-void": 0,
102 | "no-warning-comments": [0, { "terms": ["todo", "fixme", "xxx"], "location": "start" }],
103 | "no-with": 2,
104 |
105 | "block-scoped-var": 0,
106 | "brace-style": [0, "1tbs"],
107 | "camelcase": 0,
108 | "comma-dangle": [2, "never"],
109 | "comma-spacing": 0,
110 | "comma-style": 0,
111 | "complexity": [0, 11],
112 | "consistent-return": 2,
113 | "consistent-this": [0, "that"],
114 | "curly": [2, "all"],
115 | "default-case": 0,
116 | "dot-notation": [0, { "allowKeywords": true }],
117 | "eol-last": 0,
118 | "eqeqeq": 2,
119 | "func-names": 0,
120 | "func-style": [0, "declaration"],
121 | "generator-star": 0,
122 | "generator-star-spacing": 0,
123 | "global-strict": [0, "never"],
124 | "guard-for-in": 0,
125 | "handle-callback-err": 0,
126 | "indent": 0,
127 | "key-spacing": 0,
128 | "linebreak-style": [0, "windows"],
129 | "max-depth": [0, 4],
130 | "max-len": [0, 80, 4],
131 | "max-nested-callbacks": [0, 2],
132 | "max-params": [0, 3],
133 | "max-statements": [0, 10],
134 | "new-cap": 0,
135 | "new-parens": 2,
136 | "newline-after-var": 0,
137 | "one-var": 0,
138 | "operator-assignment": [0, "always"],
139 | "padded-blocks": 0,
140 | "quote-props": 0,
141 | "quotes": "error",
142 | "radix": 0,
143 | "semi": 2,
144 | "semi-spacing": [0, {"before": false, "after": true}],
145 | "sort-vars": 0,
146 | "space-after-function-name": [0, "never"],
147 | "space-after-keywords": [0, "always"],
148 | "space-before-blocks": [0, "always"],
149 | "space-before-function-paren": [0, "always"],
150 | "space-before-function-parentheses": [0, "always"],
151 | "space-in-brackets": [0, "never"],
152 | "space-in-parens": [0, "never"],
153 | "space-infix-ops": 0,
154 | "keyword-spacing": [2, {"before": true, "after": true}],
155 | "space-unary-ops": [2, { "words": true, "nonwords": false }],
156 | "spaced-line-comment": [0, "always"],
157 | "strict": 0,
158 | "use-isnan": 2,
159 | "valid-jsdoc": 0,
160 | "valid-typeof": 2,
161 | "vars-on-top": 0,
162 | "wrap-iife": 0,
163 | "wrap-regex": 0,
164 | "yoda": [2, "never"]
165 | }
166 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://docs.npmjs.com/cli/shrinkwrap#caveats
27 | node_modules
28 |
29 | # Debug log from npm
30 | npm-debug.log
31 |
32 | # Environment settings
33 | .env
34 |
35 | # Generated files and dirs
36 | public
37 |
38 | # Local resources
39 | tmp
40 | cert.pem
41 | key.pem
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "esversion": 6
3 | }
--------------------------------------------------------------------------------
/.profile:
--------------------------------------------------------------------------------
1 | echo "Installing JQ for JSON parsing ..."
2 |
3 | wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64
4 | chmod +x ./jq
5 |
6 | echo "Updating PATH to include jq ..."
7 | export PATH=$PATH:/app
8 |
9 | echo "Updating PATH to include Salesforce CLI ..."
10 | export PATH=$PATH:/app/.local/share/sfdx/cli/bin/
11 |
12 | echo "Updating Salesforce CLI plugin ..."
13 | sfdx update
14 |
15 | echo "Return version info ..."
16 | sfdx version
17 | sfdx plugins --core
18 |
19 | echo "Creating local resources ..."
20 | mkdir /app/tmp
21 |
22 | echo "Completed!"
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "stable"
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: node web.js
2 | worker: node worker.js
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Deploy to Salesforce DX
2 |
3 | An open-source and community-driven tool for one-click Salesforce DX deployments from public repositories to Scratch Orgs. You can us this tool by visiting [https://deploy-to-sfdx.com/](https://deploy-to-sfdx.com/) and logging in with your Dev Hub credentials.
4 |
5 | ## Local Setup
6 |
7 | You'll need the following setup to run this project locally.
8 |
9 | 1. Create a Salesforce DX Dev Hub. You can learn more [here](https://developer.salesforce.com/docs/atlas.en-us.sfdx_setup.meta/sfdx_setup/sfdx_setup_enable_devhub.htm).
10 |
11 | 2. Install the Salesforce CLI from [here](https://developer.salesforce.com/tools/sfdxcli).
12 |
13 | 3. Create a Connected App in your Dev Hub.
14 |
15 | - Callback: https://localhost:8443/oauth/callback
16 | - Scopes
17 |
18 | - Access your basic information (id, profile, email, address, phone)
19 | - Access and manage your data (api)
20 | - Provide access to your data via the Web (web)
21 | - Allow access to your unique identifier (openid)
22 |
23 | - Note down the consumer key and consumer secret for later.
24 |
25 | 4. Create a Postgres database in Heroku.
26 |
27 | 5. Create the `deployments` and `deployment_steps` tables by running the `deployments.sql` script against your Postgres database.
28 |
29 | 6. Create a `.env` file to store your local environment settings.
30 |
31 | 7. Update your `.env` file to include the following
32 |
33 | ```
34 | BUILDPACK_URL=https://github.com/wadewegner/sfdx-buildpack
35 | CALLBACKURL=https://localhost:8443/oauth/callback
36 | CLI_PATH=
37 | CONSUMERKEY=[your_consumer_key]
38 | CONSUMERSECRET=[your_consumer_secret]
39 | STARTINGDIRECTORY=cd tmp/;
40 | PORT=8443
41 | NODE_ENV=dev
42 | DATABASE_URL=
43 | PASS_PHRASE=
44 | CERT_PEM=
45 | KEY_PEM=
46 | ```
47 |
48 | 8. Get your Postgres `DATABASE_URL` by running `heroku config:get DATABASE_URL --app deploy-to-sfdx` and update.
49 |
50 | 9. Create your own local certificates or use these defaults:
51 |
52 | ```
53 | PASS_PHRASE=test1234
54 | CERT_PEM=-----BEGIN CERTIFICATE-----\nMIIDtTCCAp2gAwIBAgIJAIC3Ts6WBYTlMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\nBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX\naWRnaXRzIFB0eSBMdGQwHhcNMTcwOTEwMDExODQ4WhcNMTgwOTEwMDExODQ4WjBF\nMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50\nZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\nCgKCAQEAqMnT1RxpfKvc8HB8IoWMH1HSlsFyAw7Vg8I5xao6MfaydO3/C5Dw+i0P\n/CMmWdHSbhk/bOB+0FFHNYo0UOhMaxSouE+U9VHa2HZnwxvcOTJwT5NdRbPiIdkJ\n6G9CTfxe8KJV7vNlZ/ig1tZjSe/4MW5pg57d47o/Kg2YDgyeZTuR1zsxlwlR0LZS\nUhkrqG5JI8ouI7iTwdl3g3HAMV4k5AW2ox9UmAbXnvOt0DWWExcWkysYVnJ98wXs\nIv91nFFiz+P8MPhQ8EIyujerHuqZ2G2id2Wo6hVHG0o1ja4klI3F/xgcyw3CrXSD\nQcZO/CZ1nIJAffAvwaPqCY8/N9UofwIDAQABo4GnMIGkMB0GA1UdDgQWBBQ+xRiZ\nvg4qd18XG4Ivi2VEwSt3tjB1BgNVHSMEbjBsgBQ+xRiZvg4qd18XG4Ivi2VEwSt3\ntqFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV\nBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAIC3Ts6WBYTlMAwGA1UdEwQF\nMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBACPWZRPN6iAdWkAaU/FTeD4uMsw9N+Jw\npeYGNk0GVLoIXYCkr7W/X0Zoz27kqb2/QiZiKkuH2PD+VOGgKrerzQ6HFpPYEUgN\nCGNjGe6lug7o6tDGQTqD2U0YM0XS8s3nkT172NmXi/ZtAdS7qMOnO4UdD3HdOzRN\nrDVDUVtZcbC5T6iRzQ35XZgmBj+3uRq6cOOt+W8HKgu70hKPILj4k/05jfnvwXQ4\nwesGND5BgYvunr1RqdcNxKm4rqMYOC6wnz16lRAYsT33CJsd4tc7jIxX4HzOKnVI\nrNoL90NA1mU2v6jSoYCNcwvnRwZgfFhjYAxROGDSjNI2bDDXRji2Lt8=\n-----END CERTIFICATE-----\n
55 | KEY_PEM=-----BEGIN RSA PRIVATE KEY-----\nProc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,87779AB98C3E6E95\n\niA6Uc2F53GxcFMCr+Lo9y82aflMu4YeEHgUYuzFcfAvhky0GIx3Mn2IrYYHzhzkc\n+pCOLAsclhFCHhh0jOftFIXXDc2dhO/tef/IMYOozk2Qz0mMf9Ee89k5LYEFr7/o\npnov4NxIrsw70oMeXCe89HRGMfYcjQMlkD7E1OV3G+SoCefw4uzJChssz21KdMdN\n5O1GaA5s+P1U37E/ilaSfYKUksiW2T27mtv1LelhUgeYmc9E+WyV6f7FZosD0mnU\nzHmvGgHDRJJ84v3UiPJ2Kui6ELRhhyzYkYm4yhPWsNUy9R6iaSCXWibM99ME5eMl\n3horfx5/5BaXBmnpN4pnf4pIE+xO/JUSD0cl13yHJzs1ALW8XhSmEp+sPAeTYIDn\nhHDh8AXyxwQe0BPQWyhn/1a4Fcv7BRIBwmQiTvuieq0teE62PUwlQr3eU+mg2p1w\nnnM2E7dm4rEUoyR/kxKUmpS1uvw8+SauzWnrv7ooRPbcIBuqMLpGJpK7cNzwWFhA\nHAtwWy804i4vgopekBI83pFQOOwMc4I/qYHEiyRE3EHuNiEam4R3q6czE61wGNVT\ntbt4kD8cVHtIx1+pUQjSZBpo1iTIOpm86SCytEitzLIPl600kD1LUo6AL4LsI9WD\nN275OBau/FuD+PN4nlKpRzj89XSecoRsOrLmJzLdQUgwoDW62mAKgWx8tt4zTV8W\n4OuK2jPZyN72dxD6LbHdLgKGE+J9XWFeNRj/1OxJj83AylS+nH6HOvtTOsPjiaUT\nJil+ixfeEB6/TcbQ2DWFY8xJ0QkhuTLr+aqJTKKImt+HmtgpexqO5gbuybDVLcG4\nwC25ZSy9WJxgaK1OwczpodHs4z6QDw6NAZDa+wbGyH7rXu04CJHeeSuAlhWpMmtX\n8jLHPmqU1m8ctkhO4n/z6lFnxmMx3VJlNBunJodkzH9GaEt9no3OdPT62TczFyYy\nJf89noStmXbV/DK3EFzGL77w8estQKHAtsuZcXeAnd7dLOhs5+hzR2q6MW8h6nQm\nO1w7YgheBjHY2f+Kte+DJdQCp1IssYzjBq6dVlFu4Qw35vHMjlBYnnLXjB8pyPIA\n35cNGNY580dP96VNmDFGklxZQGLi2W/f4GzcSPQLcflRUJZ8YJT3pAOO1n4ATaUU\nTNN4OnwqYbrU91+pkDJPIZSoEEZErTWRMO9oTgCK68mE1NanXnMOVpgMiheq5POj\nzs8Q6HDS4XMr+prbsvXNC3GKkVLDQOSUc6wMbF9nOu3fUXgr/LOfZGBagkktP6FE\ntU0w+8PA2CUm6s4zCbW/5O0BkC4nvxTfSj5i+FVbT9gbuHjFldyoqTvzaODrcHF4\ncAId/HwdyqvE2i4jeauotyaazJZxea3rGNS0Rjum/0BHivGiPZyPb01M4HiRz2ll\ndhD7fC6O8sSxswSU6b+F5D8w8BCg7u8dX2iXXM4FEyBtvdOfFtRj6p/uKsqol3Pu\nLwt5guvYlEJOA68VnrfofFaKHqygoN7bklOhU6qoBKxdpTAve8zLTwDWymR10ZF1\nPu7NqPrcnesVuhpvylInLg1c5ccuZmsr/FwEi9C83bGMVxUXLBFUZSCEiRsmfR0F\n-----END RSA PRIVATE KEY-----\n
56 | ```
57 |
58 | ## Run Locally
59 |
60 | Once you have the above setup correctly, you can run by running `heroku local` and then browsing to [https://localhost:8443/](https://localhost:8443/).
61 |
62 | ## Updating SCSS or UX assets
63 |
64 | If you make changes to SCSS or UX assets, be sure you regenerate the `dist` files by running the command `npm run css-build`.
65 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Deploy to Salesforce DX",
3 | "description": "An application that will deploy an SFDX project from a public Github repo",
4 | "repository": "https://github.com/wadewegner/deploy-to-sfdx",
5 | "logo": "",
6 | "keywords": ["deploy", "sfdx", "salesforcedx"],
7 | "image": "",
8 | "scripts": {
9 | "postdeploy": "bin/deploy"
10 | },
11 | "env": {
12 | "CALLBACKURL": {
13 | "description": "The callback URL for your Connected App",
14 | "value": ""
15 | },
16 | "CONSUMERKEY": {
17 | "description": "The consumer key for your Connected App.",
18 | "value": ""
19 | },
20 | "CONSUMERSECRET": {
21 | "description": "The consumer secret for your Connected App.",
22 | "value": ""
23 | },
24 | "STARTINGDIRECTORY": {
25 | "description": "The base directory for the CLI",
26 | "value": ""
27 | }
28 | },
29 | "buildpacks": [{
30 | "url": "https://github.com/wadewegner/salesforce-cli-buildpack"
31 | },
32 | {
33 | "url": "heroku/nodejs"
34 | }
35 | ]
36 | }
--------------------------------------------------------------------------------
/assets/deployments.sql:
--------------------------------------------------------------------------------
1 | SET statement_timeout = 0;
2 | SET lock_timeout = 0;
3 | SET idle_in_transaction_session_timeout = 0;
4 | SET client_encoding = 'UTF8';
5 | SET standard_conforming_strings = on;
6 | SET check_function_bodies = false;
7 | SET client_min_messages = warning;
8 | SET row_security = off;
9 | SET search_path = public, pg_catalog;
10 | SET default_tablespace = '';
11 | SET default_with_oids = false;
12 |
13 | CREATE TABLE deployments (
14 | guid text NOT NULL,
15 | username text,
16 | created_at timestamp without time zone DEFAULT now(),
17 | repo text,
18 | stage text DEFAULT 'init',
19 | complete boolean DEFAULT false,
20 | error_message text,
21 | settings text,
22 | scratch_url text
23 | );
24 |
25 | CREATE TABLE deployment_steps (
26 | guid text NOT NULL,
27 | created_at timestamp without time zone DEFAULT now(),
28 | stage text,
29 | message text
30 | );
31 |
32 | CREATE SEQUENCE deployments_id_seq
33 | START WITH 1
34 | INCREMENT BY 1
35 | NO MINVALUE
36 | NO MAXVALUE
37 | CACHE 1;
38 |
39 | ALTER SEQUENCE deployments_id_seq OWNED BY deployments.guid;
40 | ALTER TABLE ONLY deployments ALTER COLUMN guid SET DEFAULT nextval('deployments_id_seq'::regclass);
41 | ALTER TABLE ONLY deployments
42 | ADD CONSTRAINT deployments_pkey PRIMARY KEY (guid);
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-144x144.png
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-192x192.png
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-36x36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-36x36.png
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-48x48.png
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-72x72.png
--------------------------------------------------------------------------------
/dist/assets/favicons/android-icon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/android-icon-96x96.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-114x114.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-120x120.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-144x144.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-152x152.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-180x180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-180x180.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-57x57.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-60x60.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-72x72.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-76x76.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon-precomposed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon-precomposed.png
--------------------------------------------------------------------------------
/dist/assets/favicons/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/apple-icon.png
--------------------------------------------------------------------------------
/dist/assets/favicons/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/favicon-16x16.png
--------------------------------------------------------------------------------
/dist/assets/favicons/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/favicon-32x32.png
--------------------------------------------------------------------------------
/dist/assets/favicons/favicon-96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/favicon-96x96.png
--------------------------------------------------------------------------------
/dist/assets/favicons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/favicon.ico
--------------------------------------------------------------------------------
/dist/assets/favicons/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "App",
3 | "icons": [
4 | {
5 | "src": "\/android-icon-36x36.png",
6 | "sizes": "36x36",
7 | "type": "image\/png",
8 | "density": "0.75"
9 | },
10 | {
11 | "src": "\/android-icon-48x48.png",
12 | "sizes": "48x48",
13 | "type": "image\/png",
14 | "density": "1.0"
15 | },
16 | {
17 | "src": "\/android-icon-72x72.png",
18 | "sizes": "72x72",
19 | "type": "image\/png",
20 | "density": "1.5"
21 | },
22 | {
23 | "src": "\/android-icon-96x96.png",
24 | "sizes": "96x96",
25 | "type": "image\/png",
26 | "density": "2.0"
27 | },
28 | {
29 | "src": "\/android-icon-144x144.png",
30 | "sizes": "144x144",
31 | "type": "image\/png",
32 | "density": "3.0"
33 | },
34 | {
35 | "src": "\/android-icon-192x192.png",
36 | "sizes": "192x192",
37 | "type": "image\/png",
38 | "density": "4.0"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/dist/assets/favicons/ms-icon-144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/ms-icon-144x144.png
--------------------------------------------------------------------------------
/dist/assets/favicons/ms-icon-150x150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/ms-icon-150x150.png
--------------------------------------------------------------------------------
/dist/assets/favicons/ms-icon-310x310.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/ms-icon-310x310.png
--------------------------------------------------------------------------------
/dist/assets/favicons/ms-icon-70x70.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/favicons/ms-icon-70x70.png
--------------------------------------------------------------------------------
/dist/assets/fonts/License-for-font.txt:
--------------------------------------------------------------------------------
1 | FONT LICENSE AGREEMENT
2 |
3 | THIS FONT LICENSE AGREEMENT (“AGREEMENT”) IS A LEGAL AGREEMENT BETWEEN YOU AND
4 | SALESFORCE.COM, INC. (“WE”, “US”, “OUR”, AND “SALESFORCE”) THAT GOVERNS YOUR
5 | ACQUISITION AND USE OF THE SALESFORCE SANS FONT (E.G., TYPEFACE, TYPOGRAPHIC
6 | CHARACTERS, ALPHANUMERICS, SYMBOLS, DESIGNS, AND ORNAMENTS) AND THE RELATED
7 | FONT FILES (E.G., TRUETYPE (TTF), WEB OPEN FONT FORMAT (WOFF,WOFF2), EMBEDDED
8 | OPENTYPE (EOT), AND SCALABLE VECTOR GRAPHICS (SVG) FILES) (COLLECTIVELY, THE
9 | “FONT”). BY DOWNLOADING OR USING THE FONT, YOU AGREE TO THE TERMS OF THIS
10 | AGREEMENT. IF YOU ARE DOWNLOADING OR USING THE FONT ON BEHALF OF A COMPANY OR
11 | OTHER LEGAL ENTITY, YOU REPRESENT THAT YOU HAVE THE AUTHORITY TO BIND SUCH
12 | ENTITY AND ITS AFFILIATES TO THIS AGREEMENT, IN WHICH CASE THE TERMS “YOU” OR
13 | “YOUR” WILL REFER TO SUCH ENTITY AND ITS AFFILIATES. IF YOU DO NOT HAVE SUCH
14 | AUTHORITY, OR IF YOU DO NOT AGREE WITH THE TERMS OF THIS AGREEMENT, YOU MUST
15 | NOT DOWNLOAD OR USE THE FONT. This Agreement was last updated on August 21,
16 | 2015. It is effective between You and Us as of the date You accept this
17 | Agreement by downloading or using the Font.
18 |
19 | 1. License Grant
20 | Subject to the terms of this Agreement and any other
21 | applicable Salesforce terms, conditions, and acceptable use policies (AUPs),
22 | We hereby grant to You a revocable, non-transferable, non-exclusive, and non-
23 | sublicenseable limited license to, without modification, reproduce and use the
24 | Font solely to create applications with the Salesforce Lightning Design System
25 | that run in Salesforce or on a Salesforce platform (e.g., Lightning, Heroku,
26 | Visualforce) (“Applications”).
27 |
28 | 2. Restrictions
29 | To the extent your Application contains copyright notices,
30 | together with all other copyright notices included with each Application, You
31 | will include the following copyright notice: “The Salesforce Sans Font is used
32 | under license from salesforce.com, inc. Copyright 2015 Salesforce.com, Inc.”
33 | You may not modify, adapt, translate, reverse engineer, decompile,
34 | disassemble, or create derivative works based on the Font. You must include
35 | the Font in an Application in a manner that does not allow a user to access
36 | the Font outside of the Application. You will not use the Font on a
37 | standalone basis and will only use the Font as part of the Salesforce
38 | Lightning Design System. You must not take any action which will have the
39 | direct or indirect effect of causing the Font to become subject to the terms
40 | of an open source license or any similar terms. You may refer to the Font as
41 | “Salesforce Sans”, but You may not use any other Salesforce trademark in
42 | connection with the Font except as may be expressly agreed to by Salesforce in
43 | writing or as set forth in other applicable Salesforce terms, conditions, and
44 | acceptable use policies (AUPs) and in any event You must comply at all times
45 | with the Salesforce Trademark and Copyright Usage Guidelines located at http:/
46 | /www2.sfdcstatic.com/assets/pdf/misc/salesforce_Trademark_Usage_Guidelines.pdf
47 | and any other supplemental guidelines that may apply to you. You must not
48 | license, sublicense, sell, resell, rent, lease, transfer, assign, distribute,
49 | time share, or otherwise commercially exploit the Font nor make the Font
50 | available to any third party, other than as expressly permitted by this
51 | Agreement. To the extent any Font documentation, style guides, or other
52 | applicable Salesforce terms, conditions, and acceptable use policies (AUPs)
53 | impose guidelines or restrictions for the use of the Font, You will abide by
54 | those guidelines and restrictions.
55 |
56 | 3. Ownership
57 | Subject to the limited rights expressly granted hereunder, We
58 | reserve all rights, title, and interest in and to the Font, including all
59 | related intellectual property rights. No rights are granted to You hereunder
60 | other than as expressly set forth herein. We shall have a royalty-free,
61 | worldwide, irrevocable, perpetual license to use and incorporate into the Font
62 | any suggestions, enhancement requests, recommendations, or other feedback
63 | provided by You.
64 |
65 | 4. Term and Termination
66 | This Agreement will take effect when you download or
67 | use the Font and will terminate upon the earlier of: (a) Your failure to
68 | comply with any term of this Agreement or any other applicable Salesforce
69 | terms, conditions, and acceptable use policies (AUPs); (b) return,
70 | destruction, or deletion of all copies of the Font in your possession; or, (c)
71 | 60 days after Salesforce provides You with written notice of termination.
72 | Salesforce’s rights and your obligations will survive the termination of this
73 | Agreement. Upon termination of this Agreement by Salesforce, if requested by
74 | Salesforce, you will destroy or delete all copies of the Font in your
75 | possession and cease using the Font in all Applications.
76 |
77 | 5. No Warranty
78 | THE FONT IS PROVIDED “AS-IS,” EXCLUSIVE OF ANY WARRANTY
79 | WHATSOEVER. WE DISCLAIM ALL IMPLIED WARRANTIES, INCLUDING WITHOUT LIMITATION
80 | ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
81 | TITLE, AND NON-INFRINGEMENT. The Font may contain bugs or errors. Any use of
82 | the Font is at Your sole risk. You acknowledge that We may discontinue making
83 | the Font available to You at any time in Our sole discretion.
84 |
85 | 6. No Damages
86 | IN NO EVENT SHALL WE HAVE ANY LIABILITY HEREUNDER TO YOU FOR
87 | ANY DAMAGES WHATSOEVER, INCLUDING BUT NOT LIMITED TO DIRECT, INDIRECT,
88 | SPECIAL, INCIDENTAL, PUNITIVE, OR CONSEQUENTIAL DAMAGES, OR DAMAGES BASED ON
89 | LOST PROFITS, DATA OR USE, HOWEVER CAUSED AND, WHETHER IN CONTRACT, TORT OR
90 | UNDER ANY OTHER THEORY OF LIABILITY, WHETHER OR NOT YOU HAVE BEEN ADVISED OF
91 | THE POSSIBILITY OF SUCH DAMAGES.
92 |
93 | 7. General Provisions
94 | You may not assign any of Your rights or obligations
95 | hereunder, whether by operation of law or otherwise, without Our prior written
96 | consent. This Agreement shall be governed exclusively by the internal laws of
97 | the State of California, without regard to its conflicts of laws rules. Each
98 | party hereby consents to the exclusive jurisdiction of the state and federal
99 | courts located in San Francisco County, California to adjudicate any dispute
100 | arising out of or relating to this Agreement. This Agreement constitutes the
101 | entire agreement between the parties, and supersedes all prior and
102 | contemporaneous agreements, proposals or representations, written or oral,
103 | concerning its subject matter. No modification, amendment, or waiver of any
104 | provision of this Agreement shall be effective unless in writing and either
105 | signed or accepted electronically by the party against whom the modification,
106 | amendment or waiver is to be asserted.
107 |
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Bold.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-BoldItalic.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Book.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Book.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Italic.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Light.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-LightItalic.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Regular.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Semibold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Semibold.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-Thin.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/SalesforceSans-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/SalesforceSans-ThinItalic.ttf
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Bold.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Bold.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-BoldItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-BoldItalic.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-BoldItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-BoldItalic.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Italic.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Italic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Italic.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Light.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Light.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-LightItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-LightItalic.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-LightItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-LightItalic.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Regular.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Regular.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Thin.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-Thin.woff2
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-ThinItalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-ThinItalic.woff
--------------------------------------------------------------------------------
/dist/assets/fonts/webfonts/SalesforceSans-ThinItalic.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/fonts/webfonts/SalesforceSans-ThinItalic.woff2
--------------------------------------------------------------------------------
/dist/assets/images/DeployToSFDX.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/dist/assets/images/launch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/images/launch.png
--------------------------------------------------------------------------------
/dist/assets/images/loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/images/loader.gif
--------------------------------------------------------------------------------
/dist/assets/images/salesforce_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wadewegner/deploy-to-sfdx/2501db3c1592c24b3cbc5b42617f46d94c15f5ba/dist/assets/images/salesforce_cloud.png
--------------------------------------------------------------------------------
/lib/apis.js:
--------------------------------------------------------------------------------
1 | const commands = require('./commands.js');
2 | const postgresHelper = require('./postgres.js');
3 |
4 | module.exports = function (router) {
5 |
6 | router.get('/test', (req, res) => {
7 |
8 | const script = 'jq --help';
9 |
10 | commands.run('test', script, (result) => {
11 | res.json({
12 | message: result
13 | });
14 | });
15 | });
16 |
17 | router.post('/status', (req, res) => {
18 |
19 | const guid = req.body.guid;
20 |
21 | postgresHelper.getDeploymentStatus(guid)
22 | .then((result) => {
23 |
24 | const rows = result.rows;
25 |
26 | let resultMessage = '';
27 | let complete = false;
28 | let scratch_url;
29 | let stage = '';
30 | let error_message = '';
31 |
32 | let count = 1;
33 |
34 | rows.forEach((row) => {
35 | const message = row.message;
36 |
37 | complete = row.complete;
38 | scratch_url = row.scratch_url;
39 | stage = row.stage;
40 | error_message = row.error_message;
41 |
42 | if (stage === 'error') {
43 | complete = true;
44 | }
45 |
46 | resultMessage = `${count}) ${message} ${resultMessage}`;
47 |
48 | count++;
49 | });
50 |
51 | res.json({
52 | message: resultMessage,
53 | complete,
54 | scratch_url,
55 | stage,
56 | error_message
57 | });
58 | });
59 | });
60 |
61 | router.post('/deploy', (req, res) => {
62 |
63 | const settings = req.body;
64 |
65 | // add additional info to the settings
66 | settings.access_token = req.cookies.access_token;
67 | settings.instance_url = req.cookies.instance_url;
68 | settings.user_name = req.cookies.user_name;
69 |
70 | // create deployment
71 | const insertQuery = `INSERT INTO deployments (guid, username, repo, settings) VALUES ('${settings.guid}', '${settings.user_name}', '${settings.githubRepo}', '${JSON.stringify(settings)}')`;
72 | postgresHelper.insertDeployment(insertQuery).then(() => {
73 | res.json({
74 | message: settings.guid
75 | });
76 | });
77 | });
78 |
79 | };
--------------------------------------------------------------------------------
/lib/commands.js:
--------------------------------------------------------------------------------
1 | const {
2 | exec
3 | } = require('child_process');
4 |
5 | exports.run = (command, commandScript) => {
6 |
7 | return new Promise((resolve) => {
8 |
9 | exec(commandScript, (err, stdout, stderr) => {
10 | if (stderr && err) {
11 | console.error('run:err', command, commandScript, stdout);
12 | resolve(null, stderr.replace(/\r?\n|\r/, '').trim());
13 | }
14 |
15 | resolve(stdout.replace(/\r?\n|\r/, '').trim(), null);
16 | });
17 | });
18 | };
--------------------------------------------------------------------------------
/lib/postgres.js:
--------------------------------------------------------------------------------
1 | const Pool = require('pg-pool');
2 | const dbUrl = require('url');
3 |
4 | const dbParams = dbUrl.parse(process.env.DATABASE_URL);
5 | const auth = dbParams.auth.split(':');
6 |
7 | const config = {
8 | host: dbParams.hostname,
9 | port: dbParams.port,
10 | user: auth[0],
11 | ssl: true,
12 | password: auth[1],
13 | database: dbParams.pathname.split('/')[1],
14 | idleTimeoutMillis: 1000,
15 | max: 10
16 | };
17 |
18 | const pool = new Pool(config);
19 |
20 | exports.getDeploymentCount = () => new Promise((resolve) => {
21 |
22 | const selectQuery = 'SELECT count(guid) FROM deployments WHERE complete = true;';
23 |
24 | pool.query(selectQuery, (queryErr, result) => {
25 | if (queryErr) {
26 | resolve(queryErr);
27 | }
28 | resolve(result);
29 | });
30 | });
31 |
32 | exports.getNewDeployment = () => new Promise((resolve, reject) => {
33 |
34 | const selectQuery = "SELECT TOP 1 guid, username, repo, settings FROM deployments WHERE stage = 'init'";
35 |
36 | pool.query(selectQuery, (queryErr, result) => {
37 | if (queryErr) {
38 | reject(queryErr);
39 | }
40 | resolve(result);
41 | });
42 | });
43 |
44 | exports.insertDeploymentStep = (guid, stage, message) => new Promise((resolve, reject) => {
45 |
46 | const insertQuery = `INSERT INTO deployment_steps (guid, stage, message) VALUES ('${guid}', '${stage}', '${message}')`;
47 |
48 | pool.query(insertQuery, (insertErr) => {
49 | if (insertErr) {
50 | console.error('insertDeploymentStep', insertErr);
51 | reject(insertErr);
52 | }
53 | resolve();
54 | });
55 | });
56 |
57 |
58 | exports.insertDeployment = insertQuery => new Promise((resolve) => {
59 |
60 | pool.query(insertQuery, (insertErr) => {
61 | if (insertErr) {
62 | console.error('insertDeployment', insertErr);
63 | resolve(insertErr);
64 | }
65 | resolve();
66 | });
67 | });
68 |
69 | exports.updateDeploymentStatus = (guid, stage) => new Promise((resolve) => {
70 |
71 | const selectQuery = `UPDATE deployments SET stage = '${stage}' WHERE guid = '${guid}'`;
72 |
73 | pool.query(selectQuery, (queryErr, result) => {
74 | if (queryErr) {
75 | console.error('updateDeploymentStatus', queryErr);
76 | resolve(queryErr);
77 | }
78 | resolve(result);
79 | });
80 | });
81 |
82 | exports.getDeploymentStatus = guid => new Promise((resolve) => {
83 |
84 | const selectQuery = `SELECT deployment_steps.message, deployment_steps.created_at, deployments.complete, deployments.stage, deployments.error_message, deployments.scratch_url FROM deployment_steps INNER JOIN deployments ON deployments.guid = deployment_steps.guid WHERE deployment_steps.guid = '${guid}' ORDER BY created_at;`;
85 |
86 | pool.query(selectQuery, (queryErr, result) => {
87 | if (queryErr) {
88 | console.error('getDeploymentStatus', queryErr);
89 | resolve(queryErr);
90 | }
91 | resolve(result);
92 | });
93 | });
94 |
95 | exports.getChoices = () => new Promise((resolve) => {
96 | const selectQuery = 'SELECT count(*) as depl, repo FROM deployments WHERE complete = true GROUP BY repo ORDER BY depl DESC';
97 |
98 | pool.query(selectQuery, (queryErr, result) => {
99 | if (queryErr) {
100 | console.error('getChoices', queryErr);
101 | resolve(queryErr);
102 | }
103 | resolve(result);
104 | });
105 | });
--------------------------------------------------------------------------------
/lib/steps.js:
--------------------------------------------------------------------------------
1 | // const commands = require('./commands.js');
2 | const postgresHelper = require('./postgres.js');
3 | const exec = require('child-process-promise').exec;
4 | // const exec = require('child_process').exec;
5 |
6 | function run(command, commandScript) {
7 |
8 | return new Promise((resolve) => {
9 |
10 | exec(commandScript, (error, stdout, stderr) => {
11 |
12 | if (stderr && error) {
13 | resolve(null, stderr.replace(/\r?\n|\r/, '').trim());
14 | } else {
15 | resolve(stdout.replace(/\r?\n|\r/, '').trim(), null);
16 | }
17 |
18 | });
19 | });
20 | }
21 |
22 | function cloneMessage(result, githubRepo) {
23 |
24 | let message = '';
25 | const stderr = result.stderr;
26 |
27 | if (stderr) {
28 | message = `Error: ${stderr}.`;
29 | } else {
30 | message = `Successfully cloned ${githubRepo}.`;
31 | }
32 |
33 | return message;
34 | }
35 |
36 | function createMessage(result) {
37 |
38 | let message = '';
39 | const stdout = result.stdout;
40 | const stderr = result.stderr;
41 |
42 | if (stderr) {
43 | message = `Error: ${stderr}.`;
44 | } else {
45 | message = `${stdout}.`;
46 | }
47 |
48 | return message;
49 | }
50 |
51 | exports.clone = (guid, script, githubRepo) => {
52 |
53 | const stage = 'clone';
54 |
55 | return postgresHelper.updateDeploymentStatus(guid, stage)
56 | .then(exec(script))
57 | .then((result) => {
58 | return cloneMessage(result, githubRepo);
59 | })
60 | .then((message) => {
61 | return postgresHelper.insertDeploymentStep(guid, stage, message)
62 | .then(() => (message));
63 | })
64 | .catch(() => {
65 |
66 | });
67 | };
68 |
69 | exports.create = (guid, script) => {
70 |
71 | const stage = 'create';
72 |
73 | return postgresHelper.updateDeploymentStatus(guid, stage)
74 | .then(exec(script))
75 | .then((result) => {
76 | return createMessage(result);
77 | })
78 | .then((message) => {
79 | return postgresHelper.insertDeploymentStep(guid, stage, message)
80 | .then(() => (message));
81 | })
82 | .catch(() => {
83 |
84 | });
85 | };
86 |
87 | exports.create2 = () => {
88 |
89 | return new Promise((resolve) => {
90 | resolve('result3');
91 | });
92 |
93 | };
--------------------------------------------------------------------------------
/lib/web.js:
--------------------------------------------------------------------------------
1 | const oauth2 = require('salesforce-oauth2');
2 | const jsforce = require('jsforce');
3 | const Guid = require('guid');
4 | const postgresHelper = require('../lib/postgres');
5 |
6 | const callbackUrl = process.env.CALLBACKURL;
7 | const consumerKey = process.env.CONSUMERKEY;
8 | const consumerSecret = process.env.CONSUMERSECRET;
9 |
10 | module.exports = function (app) {
11 |
12 | app.get('*', (req, res, next) => {
13 | if (process.env.NODE_ENV === 'production' && req.headers['x-forwarded-proto'] !== 'https') {
14 | res.redirect(`https://deploy-to-sfdx.com${req.url}`);
15 | }
16 |
17 | return next();
18 | });
19 |
20 | app.get('/', (req, res) => {
21 | postgresHelper.getDeploymentCount().then((deploymentCountResult) => {
22 |
23 | const deploymentCount = parseInt(deploymentCountResult.rows[0].count);
24 | const template = req.query.template;
25 | const referrer = req.headers.referer;
26 |
27 | res.render('pages/index', {
28 | deploymentCount,
29 | template: template ? template : referrer && referrer.startsWith('https://github.com') ? referrer : null
30 | });
31 | });
32 | });
33 |
34 | app.get('/about', (req, res) => {
35 | res.render('pages/about');
36 | });
37 |
38 | app.get('/error', (req, res) => {
39 | res.render('pages/error');
40 | });
41 |
42 | app.get('/notdevhub', (req, res) => {
43 | const template = req.query.template;
44 | const user_name = req.cookies.user_name;
45 |
46 | res.render('pages/notdevhub', {
47 | template,
48 | user_name
49 | });
50 | });
51 |
52 | app.get('/choose', (req, res) => {
53 | const user_name = req.cookies.user_name;
54 | const guid = Guid.raw();
55 |
56 | postgresHelper.getChoices()
57 | .then((result) => {
58 |
59 | res.render('pages/choose', {
60 | user_name,
61 | guid,
62 | rows: result.rows
63 | });
64 | });
65 | });
66 |
67 | app.get('/repo', (req, res) => {
68 | res.render('pages/repo', {});
69 | });
70 |
71 | app.get('/deploy', (req, res) => {
72 |
73 | const template = req.query.template;
74 | const access_token = req.cookies.access_token;
75 | const instance_url = req.cookies.instance_url;
76 | const user_name = req.cookies.user_name;
77 | const guid = Guid.raw();
78 |
79 | if (access_token && instance_url) {
80 | res.render('pages/deploy', {
81 | template,
82 | access_token,
83 | instance_url,
84 | user_name,
85 | guid
86 | });
87 | } else {
88 | if (template) {
89 | return res.redirect(`/login?template=${template}`);
90 | } else {
91 | return res.redirect('/login');
92 | }
93 | }
94 | });
95 |
96 | app.get('/deploying', (req, res) => {
97 | const template = req.query.template;
98 | const guid = req.query.guid;
99 |
100 | res.render('pages/deploying', {
101 | template,
102 | guid
103 | });
104 | });
105 |
106 | app.get('/login', (req, res) => {
107 | const template = req.query.template;
108 |
109 | const uri = oauth2.getAuthorizationUrl({
110 | redirect_uri: callbackUrl,
111 | client_id: consumerKey,
112 | scope: 'id api openid',
113 | state: template,
114 | prompt: 'select_account'
115 | });
116 |
117 | return res.redirect(uri);
118 | });
119 |
120 | app.get('/logout', (req, res) => {
121 | const access_token = req.cookies.access_token;
122 | const instance_url = req.cookies.instance_url;
123 |
124 | const conn = new jsforce.Connection({
125 | instanceUrl: instance_url,
126 | accessToken: access_token
127 | });
128 |
129 | conn.logout((err) => {
130 | if (err) {
131 | return console.error(err);
132 | }
133 | res.clearCookie('access_token');
134 | res.clearCookie('instance_url');
135 |
136 | return res.redirect('/');
137 | });
138 | });
139 |
140 | app.get('/oauth/callback', (req, res) => {
141 | const authorizationCode = req.param('code');
142 | const template = req.param('state');
143 |
144 | oauth2.authenticate({
145 | redirect_uri: callbackUrl,
146 | client_id: consumerKey,
147 | client_secret: consumerSecret,
148 | code: authorizationCode
149 | }, (error, payload) => {
150 |
151 | try {
152 |
153 | res.cookie('access_token', payload.access_token);
154 | res.cookie('instance_url', payload.instance_url);
155 |
156 | } catch (tokenErr) {
157 | console.error('payload.access_token undefined', tokenErr);
158 |
159 | return res.redirect('/error');
160 | }
161 |
162 | // check to see if org is a dev hub
163 | const conn = new jsforce.Connection({
164 | instanceUrl: payload.instance_url,
165 | accessToken: payload.access_token
166 | });
167 |
168 | conn.identity((err, identity) => {
169 | if (err) {
170 | return console.error(err);
171 | }
172 |
173 | res.cookie('user_name', identity.username);
174 |
175 | conn.tooling.query("SELECT DurableId, SettingValue FROM OrganizationSettingsDetail WHERE SettingName = 'ScratchOrgManagementPref'", (devHubErr, result) => {
176 | if (devHubErr) {
177 | return console.error(devHubErr);
178 | }
179 |
180 | if (result.size > 0) {
181 | const devHubEnabled = result.records[0].SettingValue;
182 |
183 | if (devHubEnabled === true) {
184 | if (template) {
185 | return res.redirect(`/deploy?template=${template}`);
186 | } else {
187 | return res.redirect('/choose');
188 | }
189 | } else {
190 | return res.redirect(template ? `/notdevhub?template=${template}` : '/notdevhub');
191 | }
192 | } else {
193 | return res.redirect(template ? `/notdevhub?template=${template}` : '/notdevhub');
194 | }
195 | });
196 | });
197 | });
198 | });
199 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "deploy-to-sfdx",
3 | "version": "0.0.1",
4 | "description": "An application that will deploy an SFDX project from a public Github repo",
5 | "main": "web.js",
6 | "scripts": {
7 | "start": "node .",
8 | "css-build": "mkdirp dist/assets/css && mkdirp dist/assets/fonts && ncp src/assets dist/assets && ncp src/assets/favicons dist/assets/favicons && node-sass src/scss -o dist/assets/css && ncp node_modules/@salesforce-ux/design-system/assets/fonts dist/assets/fonts",
9 | "css-watch": "node-sass --watch src/scss -o dist/assets/css"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+ssh://git@github.com/wadewegner/deploy-to-sfdx.git"
14 | },
15 | "author": "Wade Wegner",
16 | "license": "Apache-2.0",
17 | "bugs": {
18 | "url": "https://github.com/wadewegner/deploy-to-sfdx/issues"
19 | },
20 | "homepage": "https://github.com/wadewegner/deploy-to-sfdx#readme",
21 | "dependencies": {
22 | "@salesforce-ux/design-system": "^2.3.1",
23 | "amqplib": "^0.5.1",
24 | "async": "^2.5.0",
25 | "bluebird": "^3.5.1",
26 | "body-parser": "^1.17.2",
27 | "child-process-promise": "^2.2.1",
28 | "child_process": "^1.0.2",
29 | "cookie-parser": "^1.4.3",
30 | "ejs": "^2.5.6",
31 | "express": "^4.15.3",
32 | "guid": "0.0.12",
33 | "https": "^1.0.0",
34 | "jsforce": "^1.8.0",
35 | "pg": "^7.1.2",
36 | "pg-escape": "^0.2.0",
37 | "pg-pool": "^2.0.3",
38 | "pg-promise": "^7.0.3",
39 | "salesforce-oauth2": "^0.1.8",
40 | "sleep": "^5.1.1",
41 | "yamljs": "^0.3.0"
42 | },
43 | "devDependencies": {
44 | "chai": "^3.5.0",
45 | "eslint": "^3.17.1",
46 | "eslint-config-airbnb-base": "^11.1.1",
47 | "eslint-plugin-import": "^2.2.0",
48 | "mkdirp": "^0.5.1",
49 | "mocha": "^3.2.0",
50 | "ncp": "^2.0.0",
51 | "node-sass": "^4.5.3"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/scripts/choose.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 |
3 | $('#yes').click(function () {
4 |
5 | var template = $('input[name=options]:checked').val();
6 | var guid = $('input#guid').val();
7 |
8 | window.location.href = '/deploying?template=' + template + '&guid=' + guid;
9 |
10 | });
11 |
12 | $('#no').click(function () {
13 | window.location.href = '/';
14 | });
15 | });
--------------------------------------------------------------------------------
/scripts/deploy.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 |
3 | $("#yes").click(function () {
4 | var template = $('input#template').val();
5 | var guid = $('input#guid').val();
6 |
7 | window.location.href = '/deploying?template=' + template + '&guid=' + guid;
8 | });
9 |
10 | $("#no").click(function () {
11 | window.location.href = "/";
12 | });
13 | });
--------------------------------------------------------------------------------
/scripts/deploying.js:
--------------------------------------------------------------------------------
1 | $(document).ready(() => {
2 |
3 | function update_status(newMessage) {
4 |
5 | let message = '';
6 | newMessage = newMessage.replace(/^\s+|\s+$/g, '');
7 | message = `${newMessage} ${message}`;
8 |
9 | $('#status').text(message);
10 | $('#status').html($('#status').text());
11 | }
12 |
13 | function poll(guid) {
14 |
15 | var complete = false;
16 | var data = {};
17 | data.guid = guid;
18 |
19 | $.ajax({
20 | url: '/api/status',
21 | type: 'POST',
22 | data: data,
23 | success: function (response) {
24 |
25 | var message = response.message;
26 | var scratch_url = response.scratch_url;
27 | var stage = response.stage;
28 | var error_message = response.error_message;
29 |
30 | complete = response.complete;
31 |
32 | if (stage === 'error') {
33 | message = `${error_message}
15 | Deploy to Salesforce DX is a community project intended to help developers explore Salesforce DX. There is no official support, but you can log an issue at
16 | https://github.com/wadewegner/deploy-to-sfdx/issues. While every effort
17 | is made to ensure it operates without error, please use at your own risk.
18 |
19 |
20 | To learn more about Salesforce DX, take a look at these resources:
21 |
10 | Please send a message to @WadeWegner for help.
11 |
12 |
13 | If you work for Salesforce and it failed during login, it's likely the browser keeps trying to access your Org62 or GUS token (which won't work). Try a fresh browser.
14 |