@spicemod/creator 0.0.26 → 0.0.27
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/dist/bin.mjs +165 -116
- package/dist/templates/custom-app/shared/spice.config.js +6 -0
- package/dist/templates/custom-app/shared/spice.config.ts +6 -0
- package/dist/templates/custom-app/shared/tsconfig.app.json +33 -0
- package/dist/templates/custom-app/shared/tsconfig.node.json +25 -0
- package/dist/templates/custom-app/ts/react/src/extension/index.tsx +1 -1
- package/dist/templates/extension/js/react/src/app.jsx +1 -1
- package/dist/templates/extension/shared/spice.config.js +6 -0
- package/dist/templates/extension/shared/spice.config.ts +6 -0
- package/dist/templates/extension/shared/tsconfig.app.json +33 -0
- package/dist/templates/extension/shared/tsconfig.node.json +25 -0
- package/dist/templates/extension/ts/react/src/app.tsx +1 -1
- package/dist/templates/hmrCustomApp.js +284 -0
- package/dist/templates/liveReload.js +298 -45
- package/dist/templates/theme/js/react/src/app.jsx +1 -1
- package/dist/templates/theme/shared/spice.config.js +6 -0
- package/dist/templates/theme/shared/spice.config.ts +6 -0
- package/dist/templates/theme/shared/tsconfig.app.json +33 -0
- package/dist/templates/theme/shared/tsconfig.node.json +25 -0
- package/dist/templates/theme/ts/react/src/app.tsx +1 -1
- package/package.json +1 -1
- package/templates/custom-app/shared/spice.config.js +6 -0
- package/templates/custom-app/shared/spice.config.ts +6 -0
- package/templates/custom-app/shared/tsconfig.app.json +33 -0
- package/templates/custom-app/shared/tsconfig.node.json +25 -0
- package/templates/custom-app/ts/react/src/extension/index.tsx +1 -1
- package/templates/extension/js/react/src/app.jsx +1 -1
- package/templates/extension/shared/spice.config.js +6 -0
- package/templates/extension/shared/spice.config.ts +6 -0
- package/templates/extension/shared/tsconfig.app.json +33 -0
- package/templates/extension/shared/tsconfig.node.json +25 -0
- package/templates/extension/ts/react/src/app.tsx +1 -1
- package/templates/hmrCustomApp.js +284 -0
- package/templates/liveReload.js +298 -45
- package/templates/theme/js/react/src/app.jsx +1 -1
- package/templates/theme/shared/spice.config.js +6 -0
- package/templates/theme/shared/spice.config.ts +6 -0
- package/templates/theme/shared/tsconfig.app.json +33 -0
- package/templates/theme/shared/tsconfig.node.json +25 -0
- package/templates/theme/ts/react/src/app.tsx +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { Command, Option } from "commander";
|
|
|
3
3
|
import * as v from "valibot";
|
|
4
4
|
import path, { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
5
5
|
import { build, context, transform } from "esbuild";
|
|
6
|
-
import { createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
6
|
+
import fs, { createReadStream, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { watchConfig } from "c12";
|
|
8
8
|
import { globSync } from "tinyglobby";
|
|
9
9
|
import { URL as URL$1, fileURLToPath } from "node:url";
|
|
@@ -13,7 +13,7 @@ import * as p from "@clack/prompts";
|
|
|
13
13
|
import { cancel, log, spinner } from "@clack/prompts";
|
|
14
14
|
import pc from "picocolors";
|
|
15
15
|
import "dotenv/config";
|
|
16
|
-
import { readFile, writeFile } from "node:fs/promises";
|
|
16
|
+
import { readFile, unlink, writeFile } from "node:fs/promises";
|
|
17
17
|
import { parse } from "ini";
|
|
18
18
|
import { gzipSync } from "node:zlib";
|
|
19
19
|
import postcssMinify from "@csstools/postcss-minify";
|
|
@@ -137,13 +137,14 @@ const frameworks = frameworkTypes.map((name) => ({
|
|
|
137
137
|
}));
|
|
138
138
|
const frameworkOptions = toOptions(frameworks);
|
|
139
139
|
const liveReloadFilePath = dist(`templates/liveReload.js`, import.meta.url);
|
|
140
|
+
const hmrCustomAppFilePath = dist(`templates/hmrCustomApp.js`, import.meta.url);
|
|
140
141
|
const templateWrapperFilePath = dist("templates/wrapper.js", import.meta.url);
|
|
141
142
|
const customAppEntryFilePath = dist("templates/customAppEntry.js", import.meta.url);
|
|
142
143
|
|
|
143
144
|
//#endregion
|
|
144
145
|
//#region package.json
|
|
145
146
|
var name = "@spicemod/creator";
|
|
146
|
-
var version = "0.0.
|
|
147
|
+
var version = "0.0.27";
|
|
147
148
|
|
|
148
149
|
//#endregion
|
|
149
150
|
//#region src/utils/common.ts
|
|
@@ -779,15 +780,48 @@ function getTime(start) {
|
|
|
779
780
|
}
|
|
780
781
|
|
|
781
782
|
//#endregion
|
|
782
|
-
//#region src/esbuild/plugins/
|
|
783
|
-
|
|
784
|
-
|
|
783
|
+
//#region src/esbuild/plugins/buildErrorReporter.ts
|
|
784
|
+
function buildErrorReporter({ server }) {
|
|
785
|
+
return {
|
|
786
|
+
name: "spice_internal__build-error-reporter",
|
|
787
|
+
setup(build) {
|
|
788
|
+
build.onEnd(async (result) => {
|
|
789
|
+
const errors = result.errors;
|
|
790
|
+
const warnings = result.warnings;
|
|
791
|
+
if (errors.length === 0) {
|
|
792
|
+
server?.broadcast({
|
|
793
|
+
type: "build-success",
|
|
794
|
+
errors: [],
|
|
795
|
+
warnings
|
|
796
|
+
});
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
server?.broadcast({
|
|
800
|
+
type: "build-error",
|
|
801
|
+
errors,
|
|
802
|
+
warnings
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
//#endregion
|
|
810
|
+
//#region src/esbuild/plugins/clean.ts
|
|
811
|
+
const clean = (cache, logger = createLogger("plugin:clean")) => ({
|
|
812
|
+
name: "clean",
|
|
785
813
|
setup(build) {
|
|
814
|
+
const outdir = resolve(build.initialOptions.outdir || "./dist");
|
|
786
815
|
build.onStart(() => {
|
|
787
|
-
if (existsSync(
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
816
|
+
if (fs.existsSync(outdir)) try {
|
|
817
|
+
fs.rmSync(outdir, {
|
|
818
|
+
recursive: true,
|
|
819
|
+
force: true
|
|
820
|
+
});
|
|
821
|
+
logger.log(`Removed: ${outdir}`);
|
|
822
|
+
} catch (err) {
|
|
823
|
+
logger.error(`Error removing ${outdir}:`, err);
|
|
824
|
+
}
|
|
791
825
|
});
|
|
792
826
|
}
|
|
793
827
|
});
|
|
@@ -847,6 +881,37 @@ const externalGlobal = (externals, namespace = "spicetify-global") => {
|
|
|
847
881
|
|
|
848
882
|
//#endregion
|
|
849
883
|
//#region src/esbuild/plugins/spicetifyHandlers.ts
|
|
884
|
+
async function removeFile(logger, targetPath) {
|
|
885
|
+
try {
|
|
886
|
+
await unlink(targetPath);
|
|
887
|
+
logger.debug(pc.green(`${CHECK} Removed: ${targetPath}`));
|
|
888
|
+
} catch (err) {
|
|
889
|
+
if (err.code !== "ENOENT") logger.error(pc.red(`${CROSS} Failed to remove file: ${err instanceof Error ? err.message : String(err)}`));
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
async function copyFiles(logger, destDirs, cacheFiles) {
|
|
893
|
+
const tasks = [];
|
|
894
|
+
for (const filePath of cacheFiles.keys()) {
|
|
895
|
+
const fileData = cacheFiles.get(filePath);
|
|
896
|
+
if (!fileData) continue;
|
|
897
|
+
for (const destDir of destDirs) {
|
|
898
|
+
const targetPath = resolve(destDir, basename(filePath));
|
|
899
|
+
tasks.push((async () => {
|
|
900
|
+
await mkdirp(destDir);
|
|
901
|
+
await writeFile(targetPath, fileData.contents);
|
|
902
|
+
})());
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
await Promise.all(tasks);
|
|
906
|
+
}
|
|
907
|
+
async function removeDeletedFiles(logger, destDirs, removedFiles) {
|
|
908
|
+
const tasks = [];
|
|
909
|
+
for (const removedPath of removedFiles) for (const destDir of destDirs) {
|
|
910
|
+
const targetPath = resolve(destDir, basename(removedPath));
|
|
911
|
+
tasks.push(removeFile(logger, targetPath));
|
|
912
|
+
}
|
|
913
|
+
await Promise.all(tasks);
|
|
914
|
+
}
|
|
850
915
|
const spicetifyHandler = ({ config, options, cache, logger = createLogger("plugin:spicetify-handler") }) => ({
|
|
851
916
|
name: "spice_internal__spicetify-build-handler",
|
|
852
917
|
async setup(build) {
|
|
@@ -855,27 +920,23 @@ const spicetifyHandler = ({ config, options, cache, logger = createLogger("plugi
|
|
|
855
920
|
const isExtension = config.template === "extension";
|
|
856
921
|
const isCustomApp = config.template === "custom-app";
|
|
857
922
|
const identifier = isExtension ? `${urlSlugify(config.name)}.js` : urlSlugify(getEnName(config.name));
|
|
923
|
+
const getDestDirs = () => {
|
|
924
|
+
const dirs = [resolve(outDir)];
|
|
925
|
+
if (copy) dirs.push(isExtension ? getExtensionDir() : isCustomApp ? resolve(getCustomAppsDir(), identifier) : resolve(getThemesDir(), identifier));
|
|
926
|
+
return dirs;
|
|
927
|
+
};
|
|
858
928
|
if (env.skipSpicetify) {
|
|
859
929
|
logger.info(pc.yellow("skipping spicetify operations"));
|
|
860
930
|
build.onEnd(async (result) => {
|
|
861
931
|
if (result.errors.length > 0) return;
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
tasks.push((async () => {
|
|
869
|
-
await mkdirp(outDir);
|
|
870
|
-
await writeFile(targetPath, fileData.contents);
|
|
871
|
-
})());
|
|
872
|
-
}
|
|
873
|
-
try {
|
|
874
|
-
await Promise.all(tasks);
|
|
875
|
-
logger.debug(pc.green(`${CHECK} Built files written to ${outDir}`));
|
|
876
|
-
} catch (err) {
|
|
877
|
-
logger.error(pc.red(`${CROSS} Failed to write files: ${err instanceof Error ? err.message : String(err)}`));
|
|
932
|
+
const destDirs = getDestDirs();
|
|
933
|
+
await copyFiles(logger, destDirs, cache.files);
|
|
934
|
+
logger.debug(pc.green(`${CHECK} Built files written to ${outDir}`));
|
|
935
|
+
if (cache.removed.size > 0) {
|
|
936
|
+
await removeDeletedFiles(logger, destDirs, cache.removed);
|
|
937
|
+
cache.hasChanges = true;
|
|
878
938
|
}
|
|
939
|
+
cache.removed.clear();
|
|
879
940
|
});
|
|
880
941
|
return;
|
|
881
942
|
}
|
|
@@ -909,28 +970,19 @@ const spicetifyHandler = ({ config, options, cache, logger = createLogger("plugi
|
|
|
909
970
|
}
|
|
910
971
|
build.onEnd(async (result) => {
|
|
911
972
|
if (result.errors.length > 0) return;
|
|
912
|
-
|
|
913
|
-
const destDirs = [resolve(outDir)];
|
|
914
|
-
if (copy) destDirs.push(isExtension ? getExtensionDir() : isCustomApp ? resolve(getCustomAppsDir(), identifier) : resolve(getThemesDir(), identifier));
|
|
915
|
-
const tasks = [];
|
|
916
|
-
for (const filePath of cache.changed) {
|
|
917
|
-
const fileData = cache.files.get(filePath);
|
|
918
|
-
if (!fileData) continue;
|
|
919
|
-
for (const destDir of destDirs) {
|
|
920
|
-
const targetPath = resolve(destDir, basename(filePath));
|
|
921
|
-
tasks.push((async () => {
|
|
922
|
-
await mkdirp(destDir);
|
|
923
|
-
await writeFile(targetPath, fileData.contents);
|
|
924
|
-
})());
|
|
925
|
-
}
|
|
926
|
-
}
|
|
973
|
+
const destDirs = getDestDirs();
|
|
927
974
|
try {
|
|
928
|
-
await
|
|
975
|
+
await copyFiles(logger, destDirs, cache.files);
|
|
929
976
|
logger.debug(pc.green(`${CHECK} Changed files copied.`));
|
|
930
977
|
} catch (err) {
|
|
931
978
|
logger.error(pc.red(`${CROSS} Failed to copy files: ${err instanceof Error ? err.message : String(err)}`));
|
|
932
979
|
return;
|
|
933
980
|
}
|
|
981
|
+
if (cache.removed.size > 0) {
|
|
982
|
+
await removeDeletedFiles(logger, destDirs, cache.removed);
|
|
983
|
+
cache.hasChanges = true;
|
|
984
|
+
}
|
|
985
|
+
cache.removed.clear();
|
|
934
986
|
if (apply && cache.hasChanges && (!applyOnce || !hasAppliedOnce)) {
|
|
935
987
|
const { stdout, stderr, status } = runSpice(["apply"]);
|
|
936
988
|
if (status !== 0) logger.error(pc.red(`${CROSS} Spicetify apply failed:`), stdout, stderr);
|
|
@@ -951,16 +1003,32 @@ function wrapWithLoader({ config, cache, outFiles, server, dev = false, logger =
|
|
|
951
1003
|
name: namespace,
|
|
952
1004
|
setup(build$3) {
|
|
953
1005
|
if (build$3.initialOptions.write !== false) throw new Error(`[${namespace}] This plugin requires "write: false" in build options.`);
|
|
1006
|
+
build$3.onStart(() => {
|
|
1007
|
+
cache.changed.clear();
|
|
1008
|
+
cache.removed.clear();
|
|
1009
|
+
cache.hasChanges = false;
|
|
1010
|
+
});
|
|
954
1011
|
build$3.onEnd(async (res) => {
|
|
955
1012
|
try {
|
|
956
1013
|
if (res.errors.length > 0 || !res.outputFiles) return;
|
|
957
|
-
cache.changed.clear();
|
|
958
|
-
cache.hasChanges = false;
|
|
959
1014
|
const filesChanged = [];
|
|
960
1015
|
const outdir = resolve(build$3.initialOptions.outdir || "./dist");
|
|
961
1016
|
const bundledCss = getBundledCss(res.outputFiles, outdir, type, dev);
|
|
962
1017
|
const minify = build$3.initialOptions.minify;
|
|
963
1018
|
const slug = varSlugify(`${name}_${version}`);
|
|
1019
|
+
const currentFilePaths = /* @__PURE__ */ new Set();
|
|
1020
|
+
for (const file of res.outputFiles) {
|
|
1021
|
+
const isJs = file.path.endsWith(".js");
|
|
1022
|
+
const isCss = file.path.endsWith(".css");
|
|
1023
|
+
if (!dev && isCss && type === "extension") continue;
|
|
1024
|
+
const relPath = file.path.slice(outdir.length);
|
|
1025
|
+
const isCustomAppExtension = type === "custom-app" && isExtensionDir(relPath);
|
|
1026
|
+
let targetName;
|
|
1027
|
+
if (isJs) targetName = isCustomAppExtension ? outFiles.jsExtension ?? "extension.js" : outFiles.js;
|
|
1028
|
+
else if (isCss && !isCustomAppExtension) targetName = outFiles.css;
|
|
1029
|
+
if (targetName) currentFilePaths.add(join(outdir, targetName));
|
|
1030
|
+
}
|
|
1031
|
+
for (const cachedPath of cache.files.keys()) if (!currentFilePaths.has(cachedPath)) cache.removed.add(cachedPath);
|
|
964
1032
|
const transformPromises = res.outputFiles.map(async (file) => {
|
|
965
1033
|
const isJs = file.path.endsWith(".js");
|
|
966
1034
|
const isCss = file.path.endsWith(".css");
|
|
@@ -1120,8 +1188,9 @@ function getBundledCss(files, outdir, type, dev) {
|
|
|
1120
1188
|
//#region src/esbuild/plugins/index.ts
|
|
1121
1189
|
const plugins = {
|
|
1122
1190
|
css,
|
|
1123
|
-
|
|
1191
|
+
clean,
|
|
1124
1192
|
buildLogger,
|
|
1193
|
+
buildErrorReporter,
|
|
1125
1194
|
externalGlobal,
|
|
1126
1195
|
wrapWithLoader,
|
|
1127
1196
|
spicetifyHandler
|
|
@@ -1140,13 +1209,20 @@ const defaultBuildOptions = {
|
|
|
1140
1209
|
target: ["es2022", "chrome120"]
|
|
1141
1210
|
};
|
|
1142
1211
|
const getCommonPlugins = (opts) => {
|
|
1143
|
-
const { template, minify,
|
|
1212
|
+
const { template, minify, buildOptions, outFiles, server, dev } = opts;
|
|
1144
1213
|
const inline = !dev && template === "extension";
|
|
1145
|
-
|
|
1214
|
+
const cache = {
|
|
1215
|
+
files: /* @__PURE__ */ new Map(),
|
|
1216
|
+
changed: /* @__PURE__ */ new Set(),
|
|
1217
|
+
removed: /* @__PURE__ */ new Set(),
|
|
1218
|
+
hasChanges: true
|
|
1219
|
+
};
|
|
1220
|
+
const p = [
|
|
1146
1221
|
...plugins.css({
|
|
1147
1222
|
minify,
|
|
1148
1223
|
inline
|
|
1149
1224
|
}),
|
|
1225
|
+
plugins.clean(cache),
|
|
1150
1226
|
plugins.externalGlobal({
|
|
1151
1227
|
react: "Spicetify.React",
|
|
1152
1228
|
"react-dom": "Spicetify.ReactDOM",
|
|
@@ -1168,6 +1244,8 @@ const getCommonPlugins = (opts) => {
|
|
|
1168
1244
|
}),
|
|
1169
1245
|
plugins.buildLogger({ cache })
|
|
1170
1246
|
];
|
|
1247
|
+
if (dev) p.push(plugins.buildErrorReporter({ server }));
|
|
1248
|
+
return p;
|
|
1171
1249
|
};
|
|
1172
1250
|
function getEntryPoints(config) {
|
|
1173
1251
|
if (config.template === "theme") return [config.entry.js, config.entry.css];
|
|
@@ -1227,11 +1305,6 @@ function getJSBuildOptions(config, options) {
|
|
|
1227
1305
|
const entryPoints = getEntryPoints(config);
|
|
1228
1306
|
const minify = options.watch ? false : options.minify;
|
|
1229
1307
|
const outDir = resolve(config.outDir);
|
|
1230
|
-
const cache = {
|
|
1231
|
-
files: /* @__PURE__ */ new Map(),
|
|
1232
|
-
changed: /* @__PURE__ */ new Set(),
|
|
1233
|
-
hasChanges: true
|
|
1234
|
-
};
|
|
1235
1308
|
const outFiles = getOutFiles(config);
|
|
1236
1309
|
const overrides = {
|
|
1237
1310
|
...defaultBuildOptions,
|
|
@@ -1253,7 +1326,6 @@ function getJSBuildOptions(config, options) {
|
|
|
1253
1326
|
plugins: [...config.esbuildOptions?.plugins ? config.esbuildOptions.plugins : [], ...getCommonPlugins({
|
|
1254
1327
|
...config,
|
|
1255
1328
|
minify,
|
|
1256
|
-
cache,
|
|
1257
1329
|
buildOptions: {
|
|
1258
1330
|
apply: options.apply,
|
|
1259
1331
|
copy: options.copy,
|
|
@@ -1358,10 +1430,16 @@ function createPackageJSON(options) {
|
|
|
1358
1430
|
dependencies: {},
|
|
1359
1431
|
devDependencies: { "@spicetify/creator": "latest" }
|
|
1360
1432
|
};
|
|
1361
|
-
if (options.language === "ts")
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1433
|
+
if (options.language === "ts") {
|
|
1434
|
+
result.devDependencies = {
|
|
1435
|
+
...result.devDependencies,
|
|
1436
|
+
...options.packageManager === "bun" ? { "@types/bun": "^1.3.10" } : { "@types/node": "^25.5.0" }
|
|
1437
|
+
};
|
|
1438
|
+
result.peerDependencies = {
|
|
1439
|
+
...result.peerDependencies,
|
|
1440
|
+
typescript: "^5"
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1365
1443
|
const slices = [FRAMEWORKS$1[options.framework], LINTERS$1[options.linter]];
|
|
1366
1444
|
Object.values(INTERSECTIONS).forEach((intersection) => {
|
|
1367
1445
|
if (intersection.condition(options)) slices.push(intersection);
|
|
@@ -1430,7 +1508,7 @@ const SHARED_FILES = (opts) => {
|
|
|
1430
1508
|
{
|
|
1431
1509
|
from: "DOT-gitignore",
|
|
1432
1510
|
to: ".gitignore",
|
|
1433
|
-
isShared
|
|
1511
|
+
isShared
|
|
1434
1512
|
},
|
|
1435
1513
|
{
|
|
1436
1514
|
from: `spice.config.${ext(opts.language)}`,
|
|
@@ -1478,11 +1556,23 @@ const LANGUAGE_FILES = {
|
|
|
1478
1556
|
to: "jsconfig.json",
|
|
1479
1557
|
isShared: true
|
|
1480
1558
|
}],
|
|
1481
|
-
ts: [
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1559
|
+
ts: [
|
|
1560
|
+
{
|
|
1561
|
+
from: "tsconfig.json",
|
|
1562
|
+
to: "tsconfig.json",
|
|
1563
|
+
isShared: true
|
|
1564
|
+
},
|
|
1565
|
+
{
|
|
1566
|
+
from: "tsconfig.app.json",
|
|
1567
|
+
to: "tsconfig.app.json",
|
|
1568
|
+
isShared: true
|
|
1569
|
+
},
|
|
1570
|
+
{
|
|
1571
|
+
from: "tsconfig.node.json",
|
|
1572
|
+
to: "tsconfig.node.json",
|
|
1573
|
+
isShared: true
|
|
1574
|
+
}
|
|
1575
|
+
]
|
|
1486
1576
|
};
|
|
1487
1577
|
const FRAMEWORKS = {
|
|
1488
1578
|
react: ({ language, template }) => {
|
|
@@ -1648,7 +1738,7 @@ function tryGitInit(root) {
|
|
|
1648
1738
|
const downloads = { spicetify: {
|
|
1649
1739
|
from: "https://raw.githubusercontent.com/spicetify/cli/main/globals.d.ts",
|
|
1650
1740
|
to: "./src/types/spicetify.d.ts",
|
|
1651
|
-
action: (content) => content.replace("const React: any;", "const React: typeof import(\"react\");").replace("const ReactDOM: any;", "const ReactDOM: typeof import(\"react-dom/client\");").replace("const ReactDOMServer: any;", "const ReactDOMServer: typeof import(\"react-dom/server\");")
|
|
1741
|
+
action: (content) => content.replace("const React: any;", "const React: typeof import(\"react\");").replace("const ReactDOM: any;", "const ReactDOM: typeof import(\"react-dom/client\");").replace("const ReactJSX: any;", "const ReactJSX: typeof import(\"react/jsx-runtime\");").replace("const ReactDOMServer: any;", "const ReactDOMServer: typeof import(\"react-dom/server\");")
|
|
1652
1742
|
} };
|
|
1653
1743
|
async function updateTypes(isUpdating = true, cwd = process.cwd()) {
|
|
1654
1744
|
const s = spinner();
|
|
@@ -1960,7 +2050,7 @@ async function createHmrServer(config, logger = createLogger("hmrServer")) {
|
|
|
1960
2050
|
});
|
|
1961
2051
|
});
|
|
1962
2052
|
function broadcast(data) {
|
|
1963
|
-
const message =
|
|
2053
|
+
const message = JSON.stringify(data);
|
|
1964
2054
|
for (const client of clients) if (client.readyState === WebSocket.OPEN) client.send(message);
|
|
1965
2055
|
}
|
|
1966
2056
|
return {
|
|
@@ -2033,7 +2123,8 @@ const injectHMRExtension = async (rootLink, wsLink, outFiles) => {
|
|
|
2033
2123
|
_SERVER_URL: JSON.stringify(rootLink),
|
|
2034
2124
|
_HOT_RELOAD_LINK: JSON.stringify(wsLink),
|
|
2035
2125
|
_JS_PATH: JSON.stringify(`/files/${outFiles.js}`),
|
|
2036
|
-
_CSS_PATH: JSON.stringify(outFiles.css ? `/files/${outFiles.css}` : `/files/app.css`)
|
|
2126
|
+
_CSS_PATH: JSON.stringify(outFiles.css ? `/files/${outFiles.css}` : `/files/app.css`),
|
|
2127
|
+
_REMOVE_CMD: JSON.stringify(`spicetify config extensions sc-live-reload-helper.js- && spicetify apply`)
|
|
2037
2128
|
}
|
|
2038
2129
|
});
|
|
2039
2130
|
writeFileSync(outDir, code);
|
|
@@ -2083,56 +2174,20 @@ const injectHMRCustomApp = async (rootLink, wsLink, outFiles, config) => {
|
|
|
2083
2174
|
mkdirp(destDir);
|
|
2084
2175
|
const indexJsPath = resolve(destDir, "index.js");
|
|
2085
2176
|
const extensionJsPath = resolve(destDir, outFiles.jsExtension ?? "extension.js");
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
return null;
|
|
2093
|
-
});
|
|
2094
|
-
};
|
|
2095
|
-
|
|
2096
|
-
const AppWrapper = ({ appPromise }) => {
|
|
2097
|
-
const [App, setApp] = React.useState(null);
|
|
2098
|
-
|
|
2099
|
-
React.useEffect(() => {
|
|
2100
|
-
let mounted = true;
|
|
2101
|
-
|
|
2102
|
-
appPromise.then((app) => {
|
|
2103
|
-
if (mounted && app) {
|
|
2104
|
-
setApp(() => app);
|
|
2105
|
-
}
|
|
2106
|
-
});
|
|
2107
|
-
|
|
2108
|
-
return () => {
|
|
2109
|
-
mounted = false;
|
|
2110
|
-
};
|
|
2111
|
-
}, [appPromise]);
|
|
2112
|
-
|
|
2113
|
-
if (!App) {
|
|
2114
|
-
return React.createElement(
|
|
2115
|
-
"div",
|
|
2116
|
-
{ className: "loading" },
|
|
2117
|
-
"Loading app..."
|
|
2118
|
-
);
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
return React.createElement(App);
|
|
2122
|
-
};
|
|
2123
|
-
|
|
2124
|
-
const render = () => {
|
|
2125
|
-
const appPromise = waitForImport();
|
|
2126
|
-
return React.createElement(AppWrapper, { appPromise });
|
|
2127
|
-
};
|
|
2128
|
-
`);
|
|
2177
|
+
const { code: transformedIndexCode } = await transform(readFileSync(hmrCustomAppFilePath, "utf8"), {
|
|
2178
|
+
loader: "js",
|
|
2179
|
+
define: { _IMPORT_LINK: JSON.stringify(`${rootLink}/files/${outFiles.js}`) },
|
|
2180
|
+
platform: "browser"
|
|
2181
|
+
});
|
|
2182
|
+
writeFileSync(indexJsPath, transformedIndexCode);
|
|
2129
2183
|
const { code: extensionCode } = await transform(readFileSync(liveReloadFilePath, "utf8"), {
|
|
2130
2184
|
loader: "js",
|
|
2131
2185
|
define: {
|
|
2132
2186
|
_SERVER_URL: JSON.stringify(rootLink),
|
|
2133
2187
|
_HOT_RELOAD_LINK: JSON.stringify(wsLink),
|
|
2134
2188
|
_JS_PATH: JSON.stringify(`/files/${outFiles.jsExtension ?? "extension.js"}`),
|
|
2135
|
-
_CSS_PATH: JSON.stringify(outFiles.css ? `/files/${outFiles.css}` : `/files/app.css`)
|
|
2189
|
+
_CSS_PATH: JSON.stringify(outFiles.css ? `/files/${outFiles.css}` : `/files/app.css`),
|
|
2190
|
+
_REMOVE_CMD: JSON.stringify(`spicetify config custom_apps ${customAppId}- && spicetify apply`)
|
|
2136
2191
|
}
|
|
2137
2192
|
});
|
|
2138
2193
|
writeFileSync(extensionJsPath, extensionCode);
|
|
@@ -2205,11 +2260,6 @@ async function dev$1(options) {
|
|
|
2205
2260
|
function getJSDevOptions(config, options) {
|
|
2206
2261
|
const entryPoints = getEntryPoints(config);
|
|
2207
2262
|
const minify = false;
|
|
2208
|
-
const cache = {
|
|
2209
|
-
files: /* @__PURE__ */ new Map(),
|
|
2210
|
-
changed: /* @__PURE__ */ new Set(),
|
|
2211
|
-
hasChanges: true
|
|
2212
|
-
};
|
|
2213
2263
|
const overrides = {
|
|
2214
2264
|
...defaultBuildOptions,
|
|
2215
2265
|
outdir: outDir,
|
|
@@ -2228,7 +2278,6 @@ function getJSDevOptions(config, options) {
|
|
|
2228
2278
|
plugins: [...config.esbuildOptions?.plugins ? config.esbuildOptions.plugins : [], ...getCommonPlugins({
|
|
2229
2279
|
...config,
|
|
2230
2280
|
minify,
|
|
2231
|
-
cache,
|
|
2232
2281
|
buildOptions: {
|
|
2233
2282
|
copy: true,
|
|
2234
2283
|
apply: false,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
1
2
|
import { defineConfig } from "@spicetify/creator";
|
|
2
3
|
|
|
3
4
|
// Learn more: {{config-reference-link}}
|
|
@@ -7,4 +8,9 @@ export default defineConfig({
|
|
|
7
8
|
linter: "{{linter}}",
|
|
8
9
|
template: "{{template}}",
|
|
9
10
|
packageManager: "{{package-manager}}",
|
|
11
|
+
esbuildOptions: {
|
|
12
|
+
alias: {
|
|
13
|
+
"@": resolve(__dirname, "src"),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
10
16
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
1
2
|
import { defineConfig } from "@spicetify/creator";
|
|
2
3
|
|
|
3
4
|
// Learn more: {{config-reference-link}}
|
|
@@ -7,4 +8,9 @@ export default defineConfig({
|
|
|
7
8
|
linter: "{{linter}}",
|
|
8
9
|
template: "{{template}}",
|
|
9
10
|
packageManager: "{{package-manager}}",
|
|
11
|
+
esbuildOptions: {
|
|
12
|
+
alias: {
|
|
13
|
+
"@": resolve(__dirname, "src"),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
10
16
|
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"types": ["@spicetify/creator/client"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"jsx": "react-jsx",
|
|
17
|
+
|
|
18
|
+
/* Linting */
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"erasableSyntaxOnly": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"noUncheckedSideEffectImports": true,
|
|
25
|
+
|
|
26
|
+
// Paths
|
|
27
|
+
"baseUrl": ".",
|
|
28
|
+
"paths": {
|
|
29
|
+
"@/*": ["./src/*"]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"include": ["src"]
|
|
33
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023",
|
|
4
|
+
"lib": ["ES2023"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"types": ["node"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"erasableSyntaxOnly": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedSideEffectImports": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["spice.config.ts"]
|
|
25
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@/extension/app.css";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
|
-
// you can use aliases too ! (
|
|
3
|
+
// you can use aliases too ! (checkout tsconfig.app.json)
|
|
4
4
|
import Onboarding from "@/components/Onboarding";
|
|
5
5
|
|
|
6
6
|
const config = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "@/app.css";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
|
-
// you can use aliases too ! (
|
|
3
|
+
// you can use aliases too ! (checkout tsconfig.app.json)
|
|
4
4
|
import OnboardingCard from "@/components/Onboarding";
|
|
5
5
|
|
|
6
6
|
const config = {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
1
2
|
import { defineConfig } from "@spicetify/creator";
|
|
2
3
|
|
|
3
4
|
// Learn more: {{config-reference-link}}
|
|
@@ -7,4 +8,9 @@ export default defineConfig({
|
|
|
7
8
|
linter: "{{linter}}",
|
|
8
9
|
template: "{{template}}",
|
|
9
10
|
packageManager: "{{package-manager}}",
|
|
11
|
+
esbuildOptions: {
|
|
12
|
+
alias: {
|
|
13
|
+
"@": resolve(__dirname, "src"),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
10
16
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolve } from "path";
|
|
1
2
|
import { defineConfig } from "@spicetify/creator";
|
|
2
3
|
|
|
3
4
|
// Learn more: {{config-reference-link}}
|
|
@@ -7,4 +8,9 @@ export default defineConfig({
|
|
|
7
8
|
linter: "{{linter}}",
|
|
8
9
|
template: "{{template}}",
|
|
9
10
|
packageManager: "{{package-manager}}",
|
|
11
|
+
esbuildOptions: {
|
|
12
|
+
alias: {
|
|
13
|
+
"@": resolve(__dirname, "src"),
|
|
14
|
+
},
|
|
15
|
+
},
|
|
10
16
|
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"types": ["@spicetify/creator/client"],
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
|
|
10
|
+
/* Bundler mode */
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"allowImportingTsExtensions": true,
|
|
13
|
+
"verbatimModuleSyntax": true,
|
|
14
|
+
"moduleDetection": "force",
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
"jsx": "react-jsx",
|
|
17
|
+
|
|
18
|
+
/* Linting */
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"erasableSyntaxOnly": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"noUncheckedSideEffectImports": true,
|
|
25
|
+
|
|
26
|
+
// Paths
|
|
27
|
+
"baseUrl": ".",
|
|
28
|
+
"paths": {
|
|
29
|
+
"@/*": ["./src/*"]
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"include": ["src"]
|
|
33
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2023",
|
|
4
|
+
"lib": ["ES2023"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"types": ["node"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"verbatimModuleSyntax": true,
|
|
13
|
+
"moduleDetection": "force",
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"erasableSyntaxOnly": true,
|
|
21
|
+
"noFallthroughCasesInSwitch": true,
|
|
22
|
+
"noUncheckedSideEffectImports": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["spice.config.ts"]
|
|
25
|
+
}
|