@salesforce/pwa-kit-dev 3.0.0-preview.0
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 +14 -0
- package/README.md +35 -0
- package/bin/pwa-kit-dev.js +461 -0
- package/configs/babel/babel-config.js +34 -0
- package/configs/eslint/README.md +21 -0
- package/configs/eslint/eslint-config.js +11 -0
- package/configs/eslint/index.js +11 -0
- package/configs/eslint/no-react.js +18 -0
- package/configs/eslint/partials/base.js +38 -0
- package/configs/eslint/partials/jest.js +24 -0
- package/configs/eslint/partials/react.js +29 -0
- package/configs/eslint/partials/typescript-permit-any.js +31 -0
- package/configs/eslint/partials/typescript.js +17 -0
- package/configs/eslint/recommended.js +20 -0
- package/configs/eslint/safe-types.js +20 -0
- package/configs/jest/jest-babel-transform.js +19 -0
- package/configs/jest/jest.config.js +33 -0
- package/configs/jest/mocks/fileMock.js +9 -0
- package/configs/jest/mocks/styleMock.js +9 -0
- package/configs/jest/mocks/svgMock.js +11 -0
- package/configs/webpack/config-names.js +24 -0
- package/configs/webpack/config.js +425 -0
- package/configs/webpack/overrides-plugin.js +120 -0
- package/configs/webpack/plugins.js +92 -0
- package/package.json +150 -0
- package/scripts/version.js +22 -0
- package/ssr/server/build-dev-server.js +443 -0
- package/ssr/server/build-dev-server.test.js +635 -0
- package/ssr/server/loading-screen/css/main.css +272 -0
- package/ssr/server/loading-screen/css/normalize.css +349 -0
- package/ssr/server/loading-screen/img/cloud-1.svg +1 -0
- package/ssr/server/loading-screen/img/cloud-2.svg +1 -0
- package/ssr/server/loading-screen/img/cloud-3.svg +1 -0
- package/ssr/server/loading-screen/img/cloud.svg +1 -0
- package/ssr/server/loading-screen/img/codey-arm.svg +1 -0
- package/ssr/server/loading-screen/img/codey-bear.svg +1 -0
- package/ssr/server/loading-screen/img/codey-bg.svg +1 -0
- package/ssr/server/loading-screen/img/codey-cloud.svg +1 -0
- package/ssr/server/loading-screen/img/codey-search.svg +1 -0
- package/ssr/server/loading-screen/img/codey.svg +1 -0
- package/ssr/server/loading-screen/img/codeyCarry.svg +1 -0
- package/ssr/server/loading-screen/img/devDocumentation.svg +1 -0
- package/ssr/server/loading-screen/img/devGithub.svg +1 -0
- package/ssr/server/loading-screen/img/devTrailhead.svg +1 -0
- package/ssr/server/loading-screen/img/logo.svg +1 -0
- package/ssr/server/loading-screen/img/slds_spinner_brand_9EA9F1.gif +0 -0
- package/ssr/server/loading-screen/index.html +130 -0
- package/ssr/server/test_fixtures/app/main.js +6 -0
- package/ssr/server/test_fixtures/app/static/favicon.ico +0 -0
- package/ssr/server/test_fixtures/localhost.pem +45 -0
- package/utils/script-utils.js +312 -0
- package/utils/script-utils.test.js +282 -0
- package/utils/test-fixtures/minimal-built-app/ssr.js +9 -0
- package/utils/test-fixtures/minimal-built-app/static/favicon.ico +0 -0
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _fsExtra = require("fs-extra");
|
|
4
|
+
var _path = _interopRequireDefault(require("path"));
|
|
5
|
+
var _os = _interopRequireDefault(require("os"));
|
|
6
|
+
var scriptUtils = _interopRequireWildcard(require("./script-utils"));
|
|
7
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
8
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
11
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
12
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
13
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
14
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
15
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
16
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } /*
|
|
17
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
18
|
+
* All rights reserved.
|
|
19
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
20
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
21
|
+
*/
|
|
22
|
+
const pkg = (0, _fsExtra.readJsonSync)(_path.default.join(__dirname, '../package.json'));
|
|
23
|
+
describe('scriptUtils', () => {
|
|
24
|
+
const originalEnv = process.env;
|
|
25
|
+
let tmpDir;
|
|
26
|
+
beforeEach( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
27
|
+
process.env = _objectSpread({}, originalEnv);
|
|
28
|
+
tmpDir = yield (0, _fsExtra.mkdtemp)(_path.default.join(_os.default.tmpdir(), 'scriptUtils-tests'));
|
|
29
|
+
}));
|
|
30
|
+
afterEach( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
31
|
+
process.env = originalEnv;
|
|
32
|
+
tmpDir && (yield (0, _fsExtra.rm)(tmpDir, {
|
|
33
|
+
recursive: true
|
|
34
|
+
}));
|
|
35
|
+
}));
|
|
36
|
+
test('glob() with no patterns matches nothing', () => {
|
|
37
|
+
const matcher = scriptUtils.glob();
|
|
38
|
+
expect(matcher('')).toBe(false);
|
|
39
|
+
expect(matcher('a.js')).toBe(false);
|
|
40
|
+
expect(matcher()).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
describe('glob() filters correctly', () => {
|
|
43
|
+
const patterns = ['ssr.js', '**/*.jpg', '!**/no.jpg', 'abc.{js,jsx}'];
|
|
44
|
+
const matcher = scriptUtils.glob(patterns);
|
|
45
|
+
|
|
46
|
+
// Paths we expect to match
|
|
47
|
+
const expectToMatch = ['ssr.js', 'test1.jpg', 'static/test2.jpg', 'static/assets/test3.jpg', 'abc.js', 'abc.jsx'];
|
|
48
|
+
expectToMatch.forEach(path => test(`Expect path "${path}" to match`, () => {
|
|
49
|
+
expect(matcher(path)).toBe(true);
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
// Paths we expect not to match
|
|
53
|
+
const expectNotToMatch = ['ssrxjs', 'subdirectory/ssr.js', 'no.jpg', 'static/no.jpg', 'abc.jsz'];
|
|
54
|
+
expectNotToMatch.forEach(path => test(`Expect path "${path}" to NOT match`, () => {
|
|
55
|
+
expect(matcher(path)).toBe(false);
|
|
56
|
+
}));
|
|
57
|
+
const allPaths = expectToMatch.concat(expectNotToMatch);
|
|
58
|
+
test('glob works with Array.filter', () => {
|
|
59
|
+
const matched = allPaths.filter(matcher);
|
|
60
|
+
expect(matched).toHaveLength(expectToMatch.length);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
describe('CloudAPIClient', () => {
|
|
64
|
+
const username = 'user123';
|
|
65
|
+
const api_key = '123';
|
|
66
|
+
const encoded = Buffer.from(`${username}:${api_key}`, 'binary').toString('base64');
|
|
67
|
+
const expectedAuthHeader = {
|
|
68
|
+
Authorization: `Basic ${encoded}`
|
|
69
|
+
};
|
|
70
|
+
test('getAuthHeader', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
71
|
+
const client = new scriptUtils.CloudAPIClient({
|
|
72
|
+
credentials: {
|
|
73
|
+
username,
|
|
74
|
+
api_key
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
expect(client.getAuthHeader()).toEqual(expectedAuthHeader);
|
|
78
|
+
}));
|
|
79
|
+
test('getHeaders', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
80
|
+
const client = new scriptUtils.CloudAPIClient({
|
|
81
|
+
credentials: {
|
|
82
|
+
username,
|
|
83
|
+
api_key
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
expect(yield client.getHeaders()).toEqual(_objectSpread({
|
|
87
|
+
'User-Agent': `${pkg.name}@${pkg.version}`
|
|
88
|
+
}, expectedAuthHeader));
|
|
89
|
+
}));
|
|
90
|
+
});
|
|
91
|
+
test('getPkgJSON', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
92
|
+
const pkg = yield scriptUtils.getPkgJSON();
|
|
93
|
+
expect(pkg.name).toBe('@salesforce/pwa-kit-dev');
|
|
94
|
+
}));
|
|
95
|
+
describe('defaultMessage', () => {
|
|
96
|
+
test('works', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
97
|
+
const mockGit = {
|
|
98
|
+
branch: () => 'branch',
|
|
99
|
+
short: () => 'short'
|
|
100
|
+
};
|
|
101
|
+
expect(scriptUtils.defaultMessage(mockGit)).toBe('branch: short');
|
|
102
|
+
}));
|
|
103
|
+
test('works outside of a git repo', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
104
|
+
const mockGit = {
|
|
105
|
+
branch: () => {
|
|
106
|
+
throw {
|
|
107
|
+
code: 'ENOENT'
|
|
108
|
+
};
|
|
109
|
+
},
|
|
110
|
+
short: () => 'short'
|
|
111
|
+
};
|
|
112
|
+
expect(scriptUtils.defaultMessage(mockGit)).toBe('PWA Kit Bundle');
|
|
113
|
+
}));
|
|
114
|
+
test('works with any other error', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
115
|
+
const mockGit = {
|
|
116
|
+
branch: () => {
|
|
117
|
+
throw new Error();
|
|
118
|
+
},
|
|
119
|
+
short: () => 'short'
|
|
120
|
+
};
|
|
121
|
+
expect(scriptUtils.defaultMessage(mockGit)).toBe('PWA Kit Bundle');
|
|
122
|
+
}));
|
|
123
|
+
});
|
|
124
|
+
test('getCredentialsFile', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
125
|
+
expect(scriptUtils.getCredentialsFile('https://example.com', '/path/to/.mobify')).toBe('/path/to/.mobify');
|
|
126
|
+
expect(scriptUtils.getCredentialsFile('https://example.com', undefined)).toBe(_path.default.join(_os.default.homedir(), '.mobify--example.com'));
|
|
127
|
+
expect(scriptUtils.getCredentialsFile('https://cloud.mobify.com', undefined)).toBe(_path.default.join(_os.default.homedir(), '.mobify'));
|
|
128
|
+
}));
|
|
129
|
+
describe('readCredentials', () => {
|
|
130
|
+
test('should work', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
131
|
+
const creds = {
|
|
132
|
+
username: 'alice',
|
|
133
|
+
api_key: 'xyz'
|
|
134
|
+
};
|
|
135
|
+
const thePath = _path.default.join(tmpDir, '.mobify.test');
|
|
136
|
+
yield (0, _fsExtra.writeFile)(thePath, JSON.stringify(creds), 'utf8');
|
|
137
|
+
expect(yield scriptUtils.readCredentials(thePath)).toEqual(creds);
|
|
138
|
+
}));
|
|
139
|
+
test('should throw', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
140
|
+
const thePath = _path.default.join(tmpDir, '.mobify.test');
|
|
141
|
+
yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
142
|
+
return yield scriptUtils.readCredentials(thePath);
|
|
143
|
+
})).rejects.toThrow(Error);
|
|
144
|
+
}));
|
|
145
|
+
});
|
|
146
|
+
describe('createBundle', () => {
|
|
147
|
+
test('should throw if ssr_only and ssr_shared is empty', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
148
|
+
yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
149
|
+
return yield scriptUtils.createBundle({
|
|
150
|
+
message: null,
|
|
151
|
+
ssr_parameters: {},
|
|
152
|
+
ssr_only: [],
|
|
153
|
+
ssr_shared: [],
|
|
154
|
+
buildDirectory: tmpDir,
|
|
155
|
+
projectSlug: 'slug'
|
|
156
|
+
});
|
|
157
|
+
})).rejects.toThrow('no ssrOnly or ssrShared files are defined');
|
|
158
|
+
}));
|
|
159
|
+
test('should throw buildDir does not exist', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
160
|
+
yield expect( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
161
|
+
return yield scriptUtils.createBundle({
|
|
162
|
+
message: null,
|
|
163
|
+
ssr_parameters: {},
|
|
164
|
+
ssr_only: ['*.js'],
|
|
165
|
+
ssr_shared: ['*.js'],
|
|
166
|
+
buildDirectory: _path.default.join(tmpDir, 'does-not-exist'),
|
|
167
|
+
projectSlug: 'slug'
|
|
168
|
+
});
|
|
169
|
+
})).rejects.toThrow('Build directory at path');
|
|
170
|
+
}));
|
|
171
|
+
test('should archive a bundle', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
172
|
+
const message = 'message';
|
|
173
|
+
const bundle = yield scriptUtils.createBundle({
|
|
174
|
+
message,
|
|
175
|
+
ssr_parameters: {},
|
|
176
|
+
ssr_only: ['*.js'],
|
|
177
|
+
ssr_shared: ['**/*.*'],
|
|
178
|
+
buildDirectory: _path.default.join(__dirname, 'test-fixtures', 'minimal-built-app'),
|
|
179
|
+
projectSlug: 'slug'
|
|
180
|
+
});
|
|
181
|
+
expect(bundle.message).toEqual(message);
|
|
182
|
+
expect(bundle.encoding).toBe('base64');
|
|
183
|
+
expect(bundle.ssr_parameters).toEqual({});
|
|
184
|
+
expect(bundle.ssr_only).toEqual(['ssr.js']);
|
|
185
|
+
expect(bundle.ssr_shared).toEqual(['ssr.js', 'static/favicon.ico']);
|
|
186
|
+
|
|
187
|
+
// De-code and re-encode gives the same result, to show that it *is* b64 encoded
|
|
188
|
+
expect(Buffer.from(bundle.data, 'base64').toString('base64')).toEqual(bundle.data);
|
|
189
|
+
}));
|
|
190
|
+
});
|
|
191
|
+
describe('pushBundle', () => {
|
|
192
|
+
test.each([[{
|
|
193
|
+
projectSlug: 'project-slug',
|
|
194
|
+
targetSlug: undefined,
|
|
195
|
+
expectedURL: 'https://cloud.mobify.com/api/projects/project-slug/builds/',
|
|
196
|
+
status: 200
|
|
197
|
+
}], [{
|
|
198
|
+
projectSlug: 'project-slug',
|
|
199
|
+
targetSlug: 'target-slug',
|
|
200
|
+
expectedURL: 'https://cloud.mobify.com/api/projects/project-slug/builds/target-slug/',
|
|
201
|
+
status: 200
|
|
202
|
+
}], [{
|
|
203
|
+
projectSlug: 'project-slug',
|
|
204
|
+
targetSlug: undefined,
|
|
205
|
+
expectedURL: 'https://cloud.mobify.com/api/projects/project-slug/builds/',
|
|
206
|
+
status: 401
|
|
207
|
+
}]])('should push a built bundle and handle status codes (%p)', /*#__PURE__*/function () {
|
|
208
|
+
var _ref18 = _asyncToGenerator(function* ({
|
|
209
|
+
projectSlug,
|
|
210
|
+
targetSlug,
|
|
211
|
+
expectedURL,
|
|
212
|
+
status
|
|
213
|
+
}) {
|
|
214
|
+
const message = 'message';
|
|
215
|
+
const bundle = yield scriptUtils.createBundle({
|
|
216
|
+
message,
|
|
217
|
+
ssr_parameters: {},
|
|
218
|
+
ssr_only: ['*.js'],
|
|
219
|
+
ssr_shared: ['**/*.*'],
|
|
220
|
+
buildDirectory: _path.default.join(__dirname, 'test-fixtures', 'minimal-built-app'),
|
|
221
|
+
projectSlug
|
|
222
|
+
});
|
|
223
|
+
const username = 'user123';
|
|
224
|
+
const api_key = '123';
|
|
225
|
+
const credentials = {
|
|
226
|
+
username,
|
|
227
|
+
api_key
|
|
228
|
+
};
|
|
229
|
+
const goodResponseBody = {
|
|
230
|
+
anything: 'anything'
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
// Older APIs on Cloud return JSON for good responses and text for errors,
|
|
234
|
+
// hence the strange looking mock response setup.
|
|
235
|
+
const text = () => status === 200 ? Promise.resolve(JSON.stringify(goodResponseBody)) : Promise.resolve('An error occurred');
|
|
236
|
+
const json = () => status === 200 ? Promise.resolve(goodResponseBody) : Promise.reject();
|
|
237
|
+
const responseMock = {
|
|
238
|
+
status,
|
|
239
|
+
text,
|
|
240
|
+
json
|
|
241
|
+
};
|
|
242
|
+
const fetchMock = jest.fn( /*#__PURE__*/_asyncToGenerator(function* () {
|
|
243
|
+
return responseMock;
|
|
244
|
+
}));
|
|
245
|
+
const client = new scriptUtils.CloudAPIClient({
|
|
246
|
+
credentials,
|
|
247
|
+
fetch: fetchMock
|
|
248
|
+
});
|
|
249
|
+
const fn = /*#__PURE__*/function () {
|
|
250
|
+
var _ref20 = _asyncToGenerator(function* () {
|
|
251
|
+
return yield client.push(bundle, projectSlug, targetSlug);
|
|
252
|
+
});
|
|
253
|
+
return function fn() {
|
|
254
|
+
return _ref20.apply(this, arguments);
|
|
255
|
+
};
|
|
256
|
+
}();
|
|
257
|
+
|
|
258
|
+
// TODO: Split up this batch of tests to avoid conditional assertions
|
|
259
|
+
if (status === 200) {
|
|
260
|
+
// eslint-disable-next-line jest/no-conditional-expect
|
|
261
|
+
expect(yield fn()).toBe(goodResponseBody);
|
|
262
|
+
} else {
|
|
263
|
+
// eslint-disable-next-line jest/no-conditional-expect
|
|
264
|
+
yield expect(fn).rejects.toThrow('For more information visit');
|
|
265
|
+
}
|
|
266
|
+
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
267
|
+
expect(fetchMock).toHaveBeenCalledWith(expectedURL, expect.objectContaining({
|
|
268
|
+
body: expect.anything(Buffer),
|
|
269
|
+
method: 'POST',
|
|
270
|
+
headers: {
|
|
271
|
+
Authorization: expect.stringMatching(/^Basic /),
|
|
272
|
+
'Content-Length': expect.stringMatching(/^\d+$/),
|
|
273
|
+
'User-Agent': `${pkg.name}@${pkg.version}`
|
|
274
|
+
}
|
|
275
|
+
}));
|
|
276
|
+
});
|
|
277
|
+
return function (_x) {
|
|
278
|
+
return _ref18.apply(this, arguments);
|
|
279
|
+
};
|
|
280
|
+
}());
|
|
281
|
+
});
|
|
282
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2021, Salesforce, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
5
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// This file needs to exist as a text fixture, but doesn't need content!
|
|
9
|
+
"use strict";
|
|
Binary file
|