@sonolus/generate-static 5.4.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.txt ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 NonSpicyBurrito
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # Sonolus Generate Static
2
+
3
+ CLI tool to generate static Sonolus server from repository and database.
4
+
5
+ ## Links
6
+
7
+ - [Sonolus Website](https://sonolus.com)
8
+ - [Sonolus Wiki](https://wiki.sonolus.com)
9
+ - [sonolus-pack](https://github.com/Sonolus/sonolus-pack)
10
+ - [sonolus-express](https://github.com/Sonolus/sonolus-express)
11
+
12
+ ## Static Sonolus Server
13
+
14
+ While static Sonolus servers are easy to host and prepare, it has significant user experience disadvantages:
15
+
16
+ - No Sonolus client version checking.
17
+ - No localization according to user language.
18
+ - No search or pagination.
19
+ - All contents will be shown in one page.
20
+
21
+ It is recommended to develop with [sonolus-express](https://github.com/Sonolus/sonolus-express) instead.
22
+
23
+ ## Usage
24
+
25
+ ### `npx`
26
+
27
+ Use `npx` to execute without installing.
28
+
29
+ Generating using default options:
30
+
31
+ ```
32
+ npx @sonolus/generate-static
33
+ ```
34
+
35
+ Use `-h` to see a list of available options:
36
+
37
+ ```
38
+ npx @sonolus/generate-static -h
39
+ ```
40
+
41
+ ### Install Globally
42
+
43
+ Installing globally (only need once):
44
+
45
+ ```
46
+ npm i -g @sonolus/generate-static
47
+ ```
48
+
49
+ `sonolus-generate-static` will become available to use:
50
+
51
+ ```
52
+ sonolus-generate-static -h
53
+ ```
54
+
55
+ ## Input
56
+
57
+ It is recommended to use [sonolus-pack](https://github.com/Sonolus/sonolus-pack) to prepare input.
58
+
59
+ Input contains:
60
+
61
+ - `/db.json` contains information of items.
62
+ - `/repository` contains processed resources.
63
+
64
+ ## Output
65
+
66
+ Output can be statically served by a web server, and Sonolus client can connect to and play.
package/dist/index.js ADDED
@@ -0,0 +1,131 @@
1
+ #! /usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const core_1 = require("@sonolus/core");
5
+ const commander_1 = require("commander");
6
+ const fs_extra_1 = require("fs-extra");
7
+ const database_1 = require("./schemas/database");
8
+ const ordering_1 = require("./schemas/ordering");
9
+ const background_item_1 = require("./server/background-item");
10
+ const effect_item_1 = require("./server/effect-item");
11
+ const engine_item_1 = require("./server/engine-item");
12
+ const level_item_1 = require("./server/level-item");
13
+ const particle_item_1 = require("./server/particle-item");
14
+ const playlist_item_1 = require("./server/playlist-item");
15
+ const post_item_1 = require("./server/post-item");
16
+ const replay_item_1 = require("./server/replay-item");
17
+ const skin_item_1 = require("./server/skin-item");
18
+ const options = new commander_1.Command()
19
+ .name('sonolus-generate-static')
20
+ .version('5.4.0')
21
+ .option('-i, --input <value>', 'input directory', 'pack')
22
+ .option('-o, --output <value>', 'output directory', 'static')
23
+ .option('-a, --address [value]', 'address')
24
+ .option('-l, --locale <value>', 'target locale', 'en')
25
+ .option('-f, --fallback <value>', 'fallback locale', 'en')
26
+ .parse()
27
+ .opts();
28
+ const pathInput = options.input;
29
+ const pathOutput = options.output;
30
+ const address = options.address;
31
+ const targetLocale = options.locale;
32
+ const fallbackLocale = options.fallback;
33
+ const parse = (parser, path) => parser((0, fs_extra_1.readJsonSync)(path), path);
34
+ const orderDb = (db, ordering) => {
35
+ orderItems(db.posts, ordering.posts);
36
+ orderItems(db.playlists, ordering.playlists);
37
+ orderItems(db.levels, ordering.levels);
38
+ orderItems(db.skins, ordering.skins);
39
+ orderItems(db.backgrounds, ordering.backgrounds);
40
+ orderItems(db.effects, ordering.effects);
41
+ orderItems(db.particles, ordering.particles);
42
+ orderItems(db.engines, ordering.engines);
43
+ orderItems(db.replays, ordering.replays);
44
+ };
45
+ const orderItems = (items, names = []) => {
46
+ const getSortOrder = (item) => {
47
+ const index = names.indexOf(item.name);
48
+ return index === -1 ? Number.POSITIVE_INFINITY : index;
49
+ };
50
+ items.sort((a, b) => getSortOrder(a) - getSortOrder(b));
51
+ };
52
+ const outputItems = (dirname, sonolus, items, toItem) => {
53
+ items.forEach((item, index) => {
54
+ console.log('[INFO]', `${pathOutput}/sonolus/${dirname}/${item.name}`);
55
+ const itemDetails = {
56
+ item: toItem(sonolus, item),
57
+ description: sonolus.localize(item.description),
58
+ sections: [
59
+ {
60
+ title: core_1.Text.Recommended,
61
+ icon: core_1.Icon.Star,
62
+ items: items.slice(index + 1, index + 6).map((item) => toItem(sonolus, item)),
63
+ },
64
+ ],
65
+ };
66
+ (0, fs_extra_1.outputJsonSync)(`${pathOutput}/sonolus/${dirname}/${item.name}`, itemDetails);
67
+ });
68
+ console.log('[INFO]', `${pathOutput}/sonolus/${dirname}/list`);
69
+ const list = {
70
+ pageCount: 1,
71
+ items: items.map((item) => toItem(sonolus, item)),
72
+ };
73
+ (0, fs_extra_1.outputJsonSync)(`${pathOutput}/sonolus/${dirname}/list`, list);
74
+ console.log('[INFO]', `${pathOutput}/sonolus/${dirname}/info`);
75
+ const itemInfo = {
76
+ banner: sonolus.db.info.banner,
77
+ sections: [
78
+ {
79
+ title: core_1.Text.Newest,
80
+ items: items.slice(0, 5).map((item) => toItem(sonolus, item)),
81
+ },
82
+ ],
83
+ };
84
+ (0, fs_extra_1.outputJsonSync)(`${pathOutput}/sonolus/${dirname}/info`, itemInfo);
85
+ };
86
+ try {
87
+ console.log('[INFO]', 'Generating:', pathInput);
88
+ console.log();
89
+ (0, fs_extra_1.emptyDirSync)(pathOutput);
90
+ const sonolus = {
91
+ db: parse(database_1.databaseParser, `${pathInput}/db.json`),
92
+ address,
93
+ localize: (text) => (0, core_1.localize)(text, targetLocale, fallbackLocale),
94
+ };
95
+ const ordering = (0, fs_extra_1.existsSync)(`${pathInput}/ordering.json`)
96
+ ? parse(ordering_1.orderingParser, `${pathInput}/ordering.json`)
97
+ : {};
98
+ orderDb(sonolus.db, ordering);
99
+ console.log('[INFO]', `${pathOutput}/sonolus/info`);
100
+ const serverInfo = {
101
+ title: sonolus.localize(sonolus.db.info.title),
102
+ description: sonolus.db.info.description && sonolus.localize(sonolus.db.info.description),
103
+ hasAuthentication: false,
104
+ hasMultiplayer: false,
105
+ banner: sonolus.db.info.banner,
106
+ };
107
+ (0, fs_extra_1.outputJsonSync)(`${pathOutput}/sonolus/info`, serverInfo);
108
+ console.log('[INFO]', `${pathOutput}/sonolus/package`);
109
+ const packageInfo = {
110
+ shouldUpdate: false,
111
+ };
112
+ (0, fs_extra_1.outputJsonSync)(`${pathOutput}/sonolus/package`, packageInfo);
113
+ outputItems('posts', sonolus, sonolus.db.posts, post_item_1.toPostItem);
114
+ outputItems('playlists', sonolus, sonolus.db.playlists, playlist_item_1.toPlaylistItem);
115
+ outputItems('levels', sonolus, sonolus.db.levels, level_item_1.toLevelItem);
116
+ outputItems('skins', sonolus, sonolus.db.skins, skin_item_1.toSkinItem);
117
+ outputItems('backgrounds', sonolus, sonolus.db.backgrounds, background_item_1.toBackgroundItem);
118
+ outputItems('effects', sonolus, sonolus.db.effects, effect_item_1.toEffectItem);
119
+ outputItems('particles', sonolus, sonolus.db.particles, particle_item_1.toParticleItem);
120
+ outputItems('engines', sonolus, sonolus.db.engines, engine_item_1.toEngineItem);
121
+ outputItems('replays', sonolus, sonolus.db.replays, replay_item_1.toReplayItem);
122
+ console.log('[INFO]', `${pathOutput}/sonolus/repository`);
123
+ (0, fs_extra_1.copySync)(`${pathInput}/repository`, `${pathOutput}/sonolus/repository`);
124
+ console.log();
125
+ console.log('[SUCCESS]', 'Generated to:', pathOutput);
126
+ }
127
+ catch (error) {
128
+ console.log();
129
+ console.error('[FAILED]', error);
130
+ (0, fs_extra_1.removeSync)(pathOutput);
131
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseBackgroundItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseBackgroundItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(2),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ thumbnail: srl_1.srlSchema,
17
+ data: srl_1.srlSchema,
18
+ image: srl_1.srlSchema,
19
+ configuration: srl_1.srlSchema,
20
+ });
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getByName = exports.databaseParser = void 0;
4
+ const zod_1 = require("zod");
5
+ const background_item_1 = require("./background-item");
6
+ const effect_item_1 = require("./effect-item");
7
+ const engine_item_1 = require("./engine-item");
8
+ const level_item_1 = require("./level-item");
9
+ const parser_1 = require("./parser");
10
+ const particle_item_1 = require("./particle-item");
11
+ const playlist_item_1 = require("./playlist-item");
12
+ const post_item_1 = require("./post-item");
13
+ const replay_item_1 = require("./replay-item");
14
+ const server_info_1 = require("./server-info");
15
+ const skin_item_1 = require("./skin-item");
16
+ const databaseSchema = zod_1.z.object({
17
+ info: server_info_1.databaseServerInfoSchema,
18
+ posts: zod_1.z.array(post_item_1.databasePostItemSchema),
19
+ playlists: zod_1.z.array(playlist_item_1.databasePlaylistItemSchema),
20
+ levels: zod_1.z.array(level_item_1.databaseLevelItemSchema),
21
+ skins: zod_1.z.array(skin_item_1.databaseSkinItemSchema),
22
+ backgrounds: zod_1.z.array(background_item_1.databaseBackgroundItemSchema),
23
+ effects: zod_1.z.array(effect_item_1.databaseEffectItemSchema),
24
+ particles: zod_1.z.array(particle_item_1.databaseParticleItemSchema),
25
+ engines: zod_1.z.array(engine_item_1.databaseEngineItemSchema),
26
+ replays: zod_1.z.array(replay_item_1.databaseReplayItemSchema),
27
+ });
28
+ exports.databaseParser = (0, parser_1.getParser)(databaseSchema);
29
+ const getByName = (items, name, parent, path) => {
30
+ const item = items.find((item) => item.name === name);
31
+ if (!item)
32
+ throw new Error(`${parent}: ${name} not found (${path})`);
33
+ return item;
34
+ };
35
+ exports.getByName = getByName;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseEffectItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseEffectItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(5),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ thumbnail: srl_1.srlSchema,
17
+ data: srl_1.srlSchema,
18
+ audio: srl_1.srlSchema,
19
+ });
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseEngineItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseEngineItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(12),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ skin: zod_1.z.string(),
17
+ background: zod_1.z.string(),
18
+ effect: zod_1.z.string(),
19
+ particle: zod_1.z.string(),
20
+ thumbnail: srl_1.srlSchema,
21
+ playData: srl_1.srlSchema,
22
+ watchData: srl_1.srlSchema,
23
+ previewData: srl_1.srlSchema,
24
+ tutorialData: srl_1.srlSchema,
25
+ rom: srl_1.srlSchema.optional(),
26
+ configuration: srl_1.srlSchema,
27
+ });
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseLevelItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ const databaseUseItemSchema = zod_1.z.discriminatedUnion('useDefault', [
9
+ zod_1.z.object({ useDefault: zod_1.z.literal(true) }),
10
+ zod_1.z.object({ useDefault: zod_1.z.literal(false), item: zod_1.z.string() }),
11
+ ]);
12
+ exports.databaseLevelItemSchema = zod_1.z.object({
13
+ name: zod_1.z.string(),
14
+ version: zod_1.z.literal(1),
15
+ rating: zod_1.z.number(),
16
+ title: localization_text_1.localizationTextSchema,
17
+ artists: localization_text_1.localizationTextSchema,
18
+ author: localization_text_1.localizationTextSchema,
19
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
20
+ description: localization_text_1.localizationTextSchema,
21
+ engine: zod_1.z.string(),
22
+ useSkin: databaseUseItemSchema,
23
+ useBackground: databaseUseItemSchema,
24
+ useEffect: databaseUseItemSchema,
25
+ useParticle: databaseUseItemSchema,
26
+ cover: srl_1.srlSchema,
27
+ bgm: srl_1.srlSchema,
28
+ preview: srl_1.srlSchema.optional(),
29
+ data: srl_1.srlSchema,
30
+ });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localizationTextSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.localizationTextSchema = zod_1.z.record(zod_1.z.string());
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.orderingParser = void 0;
4
+ const zod_1 = require("zod");
5
+ const parser_1 = require("./parser");
6
+ const orderingSchema = zod_1.z
7
+ .object({
8
+ posts: zod_1.z.array(zod_1.z.string()),
9
+ playlists: zod_1.z.array(zod_1.z.string()),
10
+ levels: zod_1.z.array(zod_1.z.string()),
11
+ skins: zod_1.z.array(zod_1.z.string()),
12
+ backgrounds: zod_1.z.array(zod_1.z.string()),
13
+ effects: zod_1.z.array(zod_1.z.string()),
14
+ particles: zod_1.z.array(zod_1.z.string()),
15
+ engines: zod_1.z.array(zod_1.z.string()),
16
+ replays: zod_1.z.array(zod_1.z.string()),
17
+ })
18
+ .partial();
19
+ exports.orderingParser = (0, parser_1.getParser)(orderingSchema);
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getParser = void 0;
4
+ const zod_1 = require("zod");
5
+ const getParser = (schema) => (data, logPath) => {
6
+ try {
7
+ return schema.parse(data);
8
+ }
9
+ catch (error) {
10
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
11
+ if (!(error instanceof zod_1.ZodError))
12
+ throw new Error(`${logPath}: ${error}`);
13
+ const messages = error.issues.map(({ message, path }) => path.length > 0 ? `${message} (${formatPath(path)})` : message);
14
+ throw new Error([`${logPath}:`, ...messages].join(messages.length > 1 ? '\n' : ' '));
15
+ }
16
+ };
17
+ exports.getParser = getParser;
18
+ const formatPath = (path) => path.map((segment) => (typeof segment === 'number' ? `[${segment}]` : `.${segment}`)).join('');
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseParticleItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseParticleItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(3),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ thumbnail: srl_1.srlSchema,
17
+ data: srl_1.srlSchema,
18
+ texture: srl_1.srlSchema,
19
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databasePlaylistItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databasePlaylistItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(1),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ levels: zod_1.z.array(zod_1.z.string()),
17
+ thumbnail: srl_1.srlSchema.optional(),
18
+ });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databasePostItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databasePostItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(1),
11
+ title: localization_text_1.localizationTextSchema,
12
+ time: zod_1.z.number(),
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ thumbnail: srl_1.srlSchema.optional(),
17
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseReplayItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseReplayItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(1),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ level: zod_1.z.string(),
17
+ data: srl_1.srlSchema,
18
+ configuration: srl_1.srlSchema,
19
+ });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseServerInfoSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ exports.databaseServerInfoSchema = zod_1.z.object({
8
+ title: localization_text_1.localizationTextSchema,
9
+ description: localization_text_1.localizationTextSchema.optional(),
10
+ banner: srl_1.srlSchema.optional(),
11
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseSkinItemSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const localization_text_1 = require("./localization-text");
6
+ const srl_1 = require("./srl");
7
+ const tag_1 = require("./tag");
8
+ exports.databaseSkinItemSchema = zod_1.z.object({
9
+ name: zod_1.z.string(),
10
+ version: zod_1.z.literal(4),
11
+ title: localization_text_1.localizationTextSchema,
12
+ subtitle: localization_text_1.localizationTextSchema,
13
+ author: localization_text_1.localizationTextSchema,
14
+ tags: zod_1.z.array(tag_1.databaseTagSchema),
15
+ description: localization_text_1.localizationTextSchema,
16
+ thumbnail: srl_1.srlSchema,
17
+ data: srl_1.srlSchema,
18
+ texture: srl_1.srlSchema,
19
+ });
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.srlSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.srlSchema = zod_1.z.object({
6
+ hash: zod_1.z.string(),
7
+ url: zod_1.z.string(),
8
+ });
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.databaseTagSchema = void 0;
4
+ const core_1 = require("@sonolus/core");
5
+ const zod_1 = require("zod");
6
+ const localization_text_1 = require("./localization-text");
7
+ exports.databaseTagSchema = zod_1.z.object({
8
+ title: localization_text_1.localizationTextSchema,
9
+ icon: zod_1.z
10
+ .union([zod_1.z.never(), zod_1.z.never(), ...Object.values(core_1.Icon).map((icon) => zod_1.z.literal(icon))])
11
+ .optional(),
12
+ });
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toBackgroundItem = void 0;
4
+ const tag_1 = require("./tag");
5
+ const toBackgroundItem = (sonolus, item) => ({
6
+ name: item.name,
7
+ source: sonolus.address,
8
+ version: item.version,
9
+ title: sonolus.localize(item.title),
10
+ subtitle: sonolus.localize(item.subtitle),
11
+ author: sonolus.localize(item.author),
12
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
13
+ thumbnail: item.thumbnail,
14
+ data: item.data,
15
+ image: item.image,
16
+ configuration: item.configuration,
17
+ });
18
+ exports.toBackgroundItem = toBackgroundItem;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toEffectItem = void 0;
4
+ const tag_1 = require("./tag");
5
+ const toEffectItem = (sonolus, item) => ({
6
+ name: item.name,
7
+ source: sonolus.address,
8
+ version: item.version,
9
+ title: sonolus.localize(item.title),
10
+ subtitle: sonolus.localize(item.subtitle),
11
+ author: sonolus.localize(item.author),
12
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
13
+ thumbnail: item.thumbnail,
14
+ data: item.data,
15
+ audio: item.audio,
16
+ });
17
+ exports.toEffectItem = toEffectItem;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toEngineItem = void 0;
4
+ const database_1 = require("../schemas/database");
5
+ const background_item_1 = require("./background-item");
6
+ const effect_item_1 = require("./effect-item");
7
+ const particle_item_1 = require("./particle-item");
8
+ const skin_item_1 = require("./skin-item");
9
+ const tag_1 = require("./tag");
10
+ const toEngineItem = (sonolus, item) => ({
11
+ name: item.name,
12
+ source: sonolus.address,
13
+ version: item.version,
14
+ title: sonolus.localize(item.title),
15
+ subtitle: sonolus.localize(item.subtitle),
16
+ author: sonolus.localize(item.author),
17
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
18
+ skin: (0, skin_item_1.toSkinItem)(sonolus, (0, database_1.getByName)(sonolus.db.skins, item.skin, `Engine/${item.name}`, '.skin')),
19
+ background: (0, background_item_1.toBackgroundItem)(sonolus, (0, database_1.getByName)(sonolus.db.backgrounds, item.background, `Engine/${item.name}`, '.background')),
20
+ effect: (0, effect_item_1.toEffectItem)(sonolus, (0, database_1.getByName)(sonolus.db.effects, item.effect, `Engine/${item.name}`, '.effect')),
21
+ particle: (0, particle_item_1.toParticleItem)(sonolus, (0, database_1.getByName)(sonolus.db.particles, item.particle, `Engine/${item.name}`, '.particle')),
22
+ thumbnail: item.thumbnail,
23
+ playData: item.playData,
24
+ watchData: item.watchData,
25
+ previewData: item.previewData,
26
+ tutorialData: item.tutorialData,
27
+ rom: item.rom,
28
+ configuration: item.configuration,
29
+ });
30
+ exports.toEngineItem = toEngineItem;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toLevelItem = void 0;
4
+ const database_1 = require("../schemas/database");
5
+ const background_item_1 = require("./background-item");
6
+ const effect_item_1 = require("./effect-item");
7
+ const engine_item_1 = require("./engine-item");
8
+ const particle_item_1 = require("./particle-item");
9
+ const skin_item_1 = require("./skin-item");
10
+ const tag_1 = require("./tag");
11
+ const toLevelItem = (sonolus, item) => ({
12
+ name: item.name,
13
+ source: sonolus.address,
14
+ version: item.version,
15
+ rating: item.rating,
16
+ engine: (0, engine_item_1.toEngineItem)(sonolus, (0, database_1.getByName)(sonolus.db.engines, item.engine, `Level/${item.name}`, '.engine')),
17
+ useSkin: toUseItem(sonolus, skin_item_1.toSkinItem, item.useSkin, sonolus.db.skins, `Level/${item.name}`, '.useSkin.item'),
18
+ useBackground: toUseItem(sonolus, background_item_1.toBackgroundItem, item.useBackground, sonolus.db.backgrounds, `Level/${item.name}`, '.useBackground.item'),
19
+ useEffect: toUseItem(sonolus, effect_item_1.toEffectItem, item.useEffect, sonolus.db.effects, `Level/${item.name}`, '.useEffect.item'),
20
+ useParticle: toUseItem(sonolus, particle_item_1.toParticleItem, item.useParticle, sonolus.db.particles, `Level/${item.name}`, '.useParticle.item'),
21
+ title: sonolus.localize(item.title),
22
+ artists: sonolus.localize(item.artists),
23
+ author: sonolus.localize(item.author),
24
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
25
+ cover: item.cover,
26
+ bgm: item.bgm,
27
+ preview: item.preview,
28
+ data: item.data,
29
+ });
30
+ exports.toLevelItem = toLevelItem;
31
+ const toUseItem = (sonolus, toItem, useItem, items, parent, path) => useItem.useDefault
32
+ ? {
33
+ useDefault: true,
34
+ }
35
+ : {
36
+ useDefault: false,
37
+ item: toItem(sonolus, (0, database_1.getByName)(items, useItem.item, parent, path)),
38
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toParticleItem = void 0;
4
+ const tag_1 = require("./tag");
5
+ const toParticleItem = (sonolus, item) => ({
6
+ name: item.name,
7
+ source: sonolus.address,
8
+ version: item.version,
9
+ title: sonolus.localize(item.title),
10
+ subtitle: sonolus.localize(item.subtitle),
11
+ author: sonolus.localize(item.author),
12
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
13
+ thumbnail: item.thumbnail,
14
+ data: item.data,
15
+ texture: item.texture,
16
+ });
17
+ exports.toParticleItem = toParticleItem;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPlaylistItem = void 0;
4
+ const database_1 = require("../schemas/database");
5
+ const level_item_1 = require("./level-item");
6
+ const tag_1 = require("./tag");
7
+ const toPlaylistItem = (sonolus, item) => ({
8
+ name: item.name,
9
+ source: sonolus.address,
10
+ version: item.version,
11
+ title: sonolus.localize(item.title),
12
+ subtitle: sonolus.localize(item.subtitle),
13
+ author: sonolus.localize(item.author),
14
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
15
+ levels: item.levels.map((level, index) => (0, level_item_1.toLevelItem)(sonolus, (0, database_1.getByName)(sonolus.db.levels, level, `Playlist/${item.name}`, `.levels[${index}]`))),
16
+ thumbnail: item.thumbnail,
17
+ });
18
+ exports.toPlaylistItem = toPlaylistItem;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPostItem = void 0;
4
+ const tag_1 = require("./tag");
5
+ const toPostItem = (sonolus, item) => ({
6
+ name: item.name,
7
+ source: sonolus.address,
8
+ version: item.version,
9
+ title: sonolus.localize(item.title),
10
+ time: item.time,
11
+ author: sonolus.localize(item.author),
12
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
13
+ thumbnail: item.thumbnail,
14
+ });
15
+ exports.toPostItem = toPostItem;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toReplayItem = void 0;
4
+ const database_1 = require("../schemas/database");
5
+ const level_item_1 = require("./level-item");
6
+ const tag_1 = require("./tag");
7
+ const toReplayItem = (sonolus, item) => ({
8
+ name: item.name,
9
+ source: sonolus.address,
10
+ version: item.version,
11
+ title: sonolus.localize(item.title),
12
+ subtitle: sonolus.localize(item.subtitle),
13
+ author: sonolus.localize(item.author),
14
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
15
+ level: (0, level_item_1.toLevelItem)(sonolus, (0, database_1.getByName)(sonolus.db.levels, item.level, `Replay/${item.name}`, '.level')),
16
+ data: item.data,
17
+ configuration: item.configuration,
18
+ });
19
+ exports.toReplayItem = toReplayItem;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toSkinItem = void 0;
4
+ const tag_1 = require("./tag");
5
+ const toSkinItem = (sonolus, item) => ({
6
+ name: item.name,
7
+ source: sonolus.address,
8
+ version: item.version,
9
+ title: sonolus.localize(item.title),
10
+ subtitle: sonolus.localize(item.subtitle),
11
+ author: sonolus.localize(item.author),
12
+ tags: (0, tag_1.toTags)(sonolus.localize, item.tags),
13
+ thumbnail: item.thumbnail,
14
+ data: item.data,
15
+ texture: item.texture,
16
+ });
17
+ exports.toSkinItem = toSkinItem;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toTags = void 0;
4
+ const toTags = (localize, tags) => tags.map((tag) => toTag(localize, tag));
5
+ exports.toTags = toTags;
6
+ const toTag = (localize, tag) => ({
7
+ title: localize(tag.title),
8
+ icon: tag.icon,
9
+ });
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@sonolus/generate-static",
3
+ "version": "5.4.0",
4
+ "description": "CLI tool to generate static Sonolus server from repository and database",
5
+ "author": "NonSpicyBurrito",
6
+ "repository": "github:Sonolus/sonolus-generate-static",
7
+ "license": "MIT",
8
+ "keywords": [
9
+ "Sonolus"
10
+ ],
11
+ "bin": {
12
+ "sonolus-generate-static": "dist/index.js"
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "prebuild": "tsc -p . --noEmit && eslint . && prettier . --check",
19
+ "build": "tsc -p ."
20
+ },
21
+ "devDependencies": {
22
+ "@types/fs-extra": "^11.0.4",
23
+ "@typescript-eslint/eslint-plugin": "^6.12.0",
24
+ "@typescript-eslint/parser": "^6.12.0",
25
+ "eslint": "^8.54.0",
26
+ "eslint-config-prettier": "^9.0.0",
27
+ "prettier": "^3.1.0",
28
+ "prettier-plugin-organize-imports": "^3.2.4",
29
+ "typescript": "~5.2.2"
30
+ },
31
+ "dependencies": {
32
+ "@sonolus/core": "~7.5.0",
33
+ "commander": "^11.1.0",
34
+ "fs-extra": "^11.1.1",
35
+ "zod": "^3.22.4"
36
+ }
37
+ }