@ordergroove/smi-serve 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,26 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [1.7.2](https://github.com/ordergroove/plush-toys/compare/@ordergroove/smi-serve@1.7.1...@ordergroove/smi-serve@1.7.2) (2024-04-19)
7
+
8
+ **Note:** Version bump only for package @ordergroove/smi-serve
9
+
10
+
11
+
12
+
13
+
14
+ ## [1.7.1](https://github.com/ordergroove/plush-toys/compare/@ordergroove/smi-serve@1.7.0...@ordergroove/smi-serve@1.7.1) (2024-04-19)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * get hot reloading working for less ([51fd2aa](https://github.com/ordergroove/plush-toys/commit/51fd2aad37234c0f931aafc4a268b9ad996f4a7b))
20
+ * prevent FOUC when hot-reloading stylesheet ([6f6c416](https://github.com/ordergroove/plush-toys/commit/6f6c416c5b3f66f78eb0e7d0c5d2c39c2368ce7c))
21
+
22
+
23
+
24
+
25
+
6
26
  # [1.7.0](https://github.com/ordergroove/plush-toys/compare/@ordergroove/smi-serve@1.6.2...@ordergroove/smi-serve@1.7.0) (2024-04-19)
7
27
 
8
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ordergroove/smi-serve",
3
- "version": "1.7.0",
3
+ "version": "1.7.2",
4
4
  "description": "Utility to serve a SMI template locally",
5
5
  "keywords": [],
6
6
  "author": "Eugenio Lattanzio <eugenio.lattanzio@ordergroove.com>",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "homepage": "https://github.com/ordergroove/plush-toys/tree/master/packages/smi-serve#readme",
23
23
  "dependencies": {
24
- "@ordergroove/smi-precompile": "^1.9.1",
24
+ "@ordergroove/smi-precompile": "^1.10.0",
25
25
  "adm-zip": "^0.5.10",
26
26
  "esbuild": "^0.19.2",
27
27
  "esbuild-plugin-less": "^1.2.4",
@@ -32,5 +32,5 @@
32
32
  "ora": "^5.4.1",
33
33
  "yargs": "^17.7.2"
34
34
  },
35
- "gitHead": "af9f006002d62c2fe095b0d6b46c672bcd45c899"
35
+ "gitHead": "bcd26a4ae8649c4ae95019ae6ca6f9f15a45db4c"
36
36
  }
@@ -1,5 +1,6 @@
1
- // specify global variables replaced at build time so eslint doesn't error
2
- /*global OG_ENV, OG_MERCHANT_ID, OG_HMAC_AUTH, OG_SMI_CORE_VERSION*/
1
+ // virtual JSON file containing build-time variables
2
+ import { OG_ENV, OG_MERCHANT_ID, OG_HMAC_AUTH, OG_SMI_CORE_VERSION } from 'virtual:globals.json';
3
+
3
4
  const params = new URLSearchParams(window.location.search);
4
5
 
5
6
  const env = params.get('env') || OG_ENV;
@@ -1,7 +1,7 @@
1
- import './styles/main.less';
2
- import mainTemplate from './views/main.liquid';
1
+ // ~/ refers to the working directory of the project using smi-serve
2
+ import mainTemplate from '~/views/main.liquid';
3
3
 
4
- import { merchant_id, auth_config, smi_core_version } from './runtime-config';
4
+ import { merchant_id, auth_config, smi_core_version } from './devmode';
5
5
 
6
6
  // only run on initial load, not hot reload
7
7
  if (!window.og?.smi) {
@@ -3,19 +3,22 @@
3
3
  <title>SMI Demo Page</title>
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <link rel="stylesheet" href="/entrypoint.css" />
6
+ <link rel="stylesheet" href="/main.css" />
7
7
  <script>
8
8
  new EventSource('/esbuild').addEventListener('change', ev => {
9
- let stylesheet = document.querySelector('link');
9
+ console.log('File changed, running hot reload');
10
+ let stylesheet = document.querySelector('link[rel="stylesheet"]');
10
11
  try {
11
12
  const { updated, added } = JSON.parse(ev.data);
12
13
  const ts = new Date().getTime();
13
- if (updated.includes('/entrypoint.css') || added.includes('/entrypoint.css')) {
14
- document.head.removeChild(stylesheet);
15
- stylesheet = document.createElement('link');
16
- stylesheet.rel = 'stylesheet';
17
- stylesheet.href = '/entrypoint.css?_=' + ts;
18
- document.head.appendChild(stylesheet);
14
+ if (updated.includes('/main.css') || added.includes('/main.css')) {
15
+ // https://esbuild.github.io/api/#hot-reloading-css
16
+ const newStylesheet = document.createElement('link');
17
+ newStylesheet.rel = 'stylesheet';
18
+ newStylesheet.href = '/main.css?_=' + ts;
19
+ // wait until new stylesheet has loading to prevent FOUC
20
+ newStylesheet.onload = () => stylesheet.remove();
21
+ document.head.appendChild(newStylesheet);
19
22
  }
20
23
  if (updated.includes('/entrypoint.js')) {
21
24
  import('./entrypoint.js?_=' + ts).then(({ mainTemplate }) => {
package/src/serve.js CHANGED
@@ -8,7 +8,7 @@ const { getValidLoginAndCurrentMerchant } = require('./auth');
8
8
  const { open, getcwd, glob, readPackageJson, packageJsonKeys } = require('./utils');
9
9
  const { impersonate } = require('./impersonate');
10
10
 
11
- const setupSmiDevMode = async argv => {
11
+ async function getGlobals(argv) {
12
12
  let hmacAuth = "''",
13
13
  merchant,
14
14
  customer,
@@ -17,13 +17,23 @@ const setupSmiDevMode = async argv => {
17
17
  if ('impersonate' in argv) {
18
18
  [_token, merchant, customer] = await impersonate(argv);
19
19
 
20
- hmacAuth = customer && JSON.stringify([customer.merchant_user_id, customer.ts, customer.hash].join('|'));
20
+ hmacAuth = customer && [customer.merchant_user_id, customer.ts, customer.hash].join('|');
21
21
  }
22
22
 
23
23
  const packageJson = readPackageJson();
24
24
  const smiCoreVersion = packageJson[packageJsonKeys.OG_SECTION]?.[packageJsonKeys.CORE_VERSION] || 'latest';
25
25
 
26
26
  return {
27
+ OG_MERCHANT_ID: merchant ? merchant.public_id : '',
28
+ OG_HMAC_AUTH: hmacAuth,
29
+ OG_ENV: argv.env,
30
+ OG_SMI_CORE_VERSION: smiCoreVersion
31
+ };
32
+ }
33
+
34
+ const smiDevModePlugin = globals => {
35
+ /** @type {import('esbuild').Plugin} */
36
+ const plugin = {
27
37
  name: 'resolve_smi_templates',
28
38
  setup(build) {
29
39
  build.onLoad({ filter: /main\.liquid/ }, async () => {
@@ -48,50 +58,31 @@ const setupSmiDevMode = async argv => {
48
58
  };
49
59
  });
50
60
 
51
- build.onResolve({ filter: /(^entrypoint\.js$|^\.\/runtime-config(\.js)?$)/ }, args => {
52
- const c = {
61
+ // allow importing a non-existent 'virtual:globals.json' file containing build-time variables
62
+ const virtualGlobalsFilter = /^virtual:globals.json$/;
63
+ build.onResolve({ filter: virtualGlobalsFilter }, args => {
64
+ return {
53
65
  path: args.path,
54
- namespace: 'entrypoint-ns'
66
+ namespace: 'virtual-globals'
67
+ };
68
+ });
69
+ build.onLoad({ filter: virtualGlobalsFilter }, () => {
70
+ return {
71
+ contents: JSON.stringify(globals),
72
+ loader: 'json'
55
73
  };
56
- return c;
57
74
  });
58
75
 
59
- // Load paths tagged with the "env-ns" namespace and behave as if
60
- // they point to a JSON file containing the environment variables.
61
- build.onLoad({ filter: /(^entrypoint\.js$|^\.\/runtime-config(\.js)?$)/ }, async args => {
62
- // all this files have been resolved by precompile, here is only to list them in bundle
63
- if (args.path === 'entrypoint.js')
64
- return {
65
- contents: fs.existsSync(`${getcwd()}/${args.path}`)
66
- ? fs.readFileSync(`${getcwd()}/${args.path}`)
67
- : fs.readFileSync(`${__dirname}/partials/entrypoint.js`),
68
- resolveDir: getcwd(),
69
- loader: 'js',
70
- watchFiles: [path.resolve('./styles/main.less'), path.resolve('./views/main.liquid')]
71
- };
72
-
73
- if (args.path === './runtime-config') {
74
- const smiIndexSource = (
75
- await esbuild.transform(fs.readFileSync(`${__dirname}/partials/devmode.js`, 'utf8'), {
76
- define: {
77
- OG_MERCHANT_ID: merchant ? JSON.stringify(merchant.public_id) : "''",
78
- OG_HMAC_AUTH: hmacAuth,
79
- OG_ENV: JSON.stringify(argv.env),
80
- OG_SMI_CORE_VERSION: JSON.stringify(smiCoreVersion)
81
- }
82
- })
83
- ).code;
84
-
85
- return {
86
- contents: smiIndexSource,
87
- loader: 'js',
88
- resolveDir: getcwd()
89
- };
90
- }
91
- throw new Error('Invalid loader');
76
+ // take imports starting with ~/ and resolve them inside the current working directory
77
+ build.onResolve({ filter: /^~\// }, args => {
78
+ return build.resolve(args.path.replace('~/', './'), {
79
+ kind: 'import-statement',
80
+ resolveDir: getcwd()
81
+ });
92
82
  });
93
83
  }
94
84
  };
85
+ return plugin;
95
86
  };
96
87
 
97
88
  async function serve(argv) {
@@ -111,10 +102,12 @@ async function serve(argv) {
111
102
  const smiIndexSource = fs.readFileSync(`${__dirname}/partials/index.html`, 'utf8');
112
103
  fs.writeFileSync(smiIndexFile, smiIndexSource, { encoding: 'utf8' });
113
104
 
105
+ const globals = await getGlobals(argv);
106
+
107
+ /** @type {import('esbuild').BuildOptions} */
114
108
  const buildConf = {
115
- entryPoints: {
116
- entrypoint: 'entrypoint.js'
117
- },
109
+ entryPoints: [path.join(__dirname, 'partials', 'entrypoint.js'), mainLess],
110
+ entryNames: '[name]',
118
111
 
119
112
  logLevel: verbose ? 'verbose' : 'error',
120
113
  nodePaths: [path.join(getcwd(), 'node_modules')],
@@ -128,7 +121,7 @@ async function serve(argv) {
128
121
  sourcemap: true,
129
122
 
130
123
  outdir: path.join(getcwd(), outdir),
131
- plugins: [await setupSmiDevMode(argv), lessLoader()]
124
+ plugins: [smiDevModePlugin(globals), lessLoader()]
132
125
  };
133
126
 
134
127
  if (!mainLess) {