@runwell/shopify-toolkit 0.14.0 → 0.14.1
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/lib/sync.js +44 -2
- package/package.json +1 -1
package/lib/sync.js
CHANGED
|
@@ -27,9 +27,19 @@ export async function sync(flags) {
|
|
|
27
27
|
await syncBaseline({ baselineRoot, targetDir, config, dryRun, written: writtenFiles });
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
// Modules to sync = explicit tenant config PLUS any module whose manifest
|
|
31
|
+
// declares always_enabled: true. The latter ensures foundation modules
|
|
32
|
+
// (css-tokens, css-typography) sync without requiring every tenant config
|
|
33
|
+
// to list them. Tenant config still wins for resolution (variant, config
|
|
34
|
+
// overrides), but always_enabled modules are auto-included.
|
|
35
|
+
const explicitModules = Object.keys(config.modules);
|
|
36
|
+
const alwaysEnabledModules = discoverAlwaysEnabledModules(flags.toolkitRoot, explicitModules);
|
|
37
|
+
const moduleNames = [...explicitModules, ...alwaysEnabledModules];
|
|
38
|
+
if (alwaysEnabledModules.length && verbose) {
|
|
39
|
+
console.log(`Auto-including always_enabled modules: ${alwaysEnabledModules.join(', ')}`);
|
|
40
|
+
}
|
|
31
41
|
for (const moduleName of moduleNames) {
|
|
32
|
-
const cfgEntry = config.modules[moduleName];
|
|
42
|
+
const cfgEntry = config.modules[moduleName] || { enabled: true, config: {} };
|
|
33
43
|
if (cfgEntry.enabled === false) {
|
|
34
44
|
if (verbose) console.log(`[skip] ${moduleName} (disabled)`);
|
|
35
45
|
continue;
|
|
@@ -131,3 +141,35 @@ function getToolkitVersion(toolkitRoot) {
|
|
|
131
141
|
return pkg.version;
|
|
132
142
|
} catch { return 'unknown'; }
|
|
133
143
|
}
|
|
144
|
+
|
|
145
|
+
function discoverAlwaysEnabledModules(toolkitRoot, explicitModules) {
|
|
146
|
+
// Walks modules/ for top-level dirs AND modules/_shared/* for foundation modules.
|
|
147
|
+
// Returns names of any module whose module.json declares always_enabled: true,
|
|
148
|
+
// skipping those already in the explicit tenant config.
|
|
149
|
+
const modulesDir = path.join(toolkitRoot, 'modules');
|
|
150
|
+
if (!fs.existsSync(modulesDir)) return [];
|
|
151
|
+
const candidates = [];
|
|
152
|
+
for (const entry of fs.readdirSync(modulesDir)) {
|
|
153
|
+
if (entry.startsWith('.')) continue;
|
|
154
|
+
const fullPath = path.join(modulesDir, entry);
|
|
155
|
+
if (!fs.statSync(fullPath).isDirectory()) continue;
|
|
156
|
+
if (entry === '_shared') {
|
|
157
|
+
for (const sub of fs.readdirSync(fullPath)) {
|
|
158
|
+
if (sub.startsWith('.')) continue;
|
|
159
|
+
const subPath = path.join(fullPath, sub);
|
|
160
|
+
if (fs.statSync(subPath).isDirectory()) candidates.push(`_shared/${sub}`);
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
candidates.push(entry);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
const out = [];
|
|
167
|
+
for (const name of candidates) {
|
|
168
|
+
if (explicitModules.includes(name)) continue;
|
|
169
|
+
try {
|
|
170
|
+
const manifest = loadModuleManifest(toolkitRoot, name);
|
|
171
|
+
if (manifest.always_enabled === true) out.push(name);
|
|
172
|
+
} catch { /* skip modules without a manifest */ }
|
|
173
|
+
}
|
|
174
|
+
return out;
|
|
175
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runwell/shopify-toolkit",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Reusable Shopify theme modules from Runwell. Replaces typically app-driven features (reviews, wishlist, urgency, FAQ, post-purchase upsell, exit popups, free-ship progress, sticky ATC, testimonials, badges, bundles) with native Liquid + JS + CSS that ship across multiple client themes via a config-driven sync CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|