create-supaslidev 0.1.4 → 0.2.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/dist/cli.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
-
3
2
  //#region src/cli.d.ts
4
3
  declare function run(): Promise<void>;
5
4
  //#endregion
package/dist/cli.js CHANGED
@@ -1,19 +1,16 @@
1
1
  #!/usr/bin/env node
2
-
3
2
  import { Command } from "commander";
4
3
  import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
5
4
  import { basename, dirname, join, relative } from "node:path";
6
- import { fileURLToPath, pathToFileURL } from "node:url";
5
+ import { fileURLToPath } from "node:url";
7
6
  import { spawn } from "node:child_process";
8
7
  import * as p from "@clack/prompts";
9
8
  import ejs from "ejs";
10
9
  import pc from "picocolors";
11
10
  import { tmpdir } from "node:os";
12
-
11
+ //#endregion
13
12
  //#region src/version.ts
14
- const __dirname = dirname(fileURLToPath(import.meta.url));
15
- const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
16
- const CLI_VERSION = pkg.version;
13
+ const CLI_VERSION = "0.2.1";
17
14
  const PACKAGE_NAME = "@supaslidev/cli";
18
15
  const CACHE_DIR = join(tmpdir(), "supaslidev-cli");
19
16
  const CACHE_FILE = join(CACHE_DIR, "version-cache.json");
@@ -43,11 +40,10 @@ function readCache() {
43
40
  function writeCache(latestVersion) {
44
41
  try {
45
42
  if (!existsSync(CACHE_DIR)) mkdirSync(CACHE_DIR, { recursive: true });
46
- const cache = {
43
+ writeFileSync(CACHE_FILE, JSON.stringify({
47
44
  latestVersion,
48
45
  checkedAt: Date.now()
49
- };
50
- writeFileSync(CACHE_FILE, JSON.stringify(cache));
46
+ }));
51
47
  } catch {}
52
48
  }
53
49
  async function fetchLatestPackageVersion(packageName) {
@@ -86,7 +82,6 @@ function checkForUpdatesCached() {
86
82
  updateAvailable: latestVersion ? compareVersions(CLI_VERSION, latestVersion) : false
87
83
  };
88
84
  }
89
-
90
85
  //#endregion
91
86
  //#region src/create.ts
92
87
  const SUPASLIDEV_FALLBACK_VERSION = "0.1.4";
@@ -158,11 +153,7 @@ async function renderTemplatesRecursively(sourceDir, targetDir, data) {
158
153
  }
159
154
  }
160
155
  function createDirectoryStructure(targetDir) {
161
- for (const dir of [
162
- "presentations",
163
- "packages",
164
- "scripts"
165
- ]) {
156
+ for (const dir of ["presentations", "packages"]) {
166
157
  const fullPath = join(targetDir, dir);
167
158
  mkdirSync(fullPath, { recursive: true });
168
159
  trackPath(fullPath);
@@ -221,90 +212,7 @@ Add your content here
221
212
  [Slidev Documentation](https://sli.dev/)
222
213
  `;
223
214
  writeFileSync(join(presentationDir, "slides.md"), slidesContent, "utf-8");
224
- writeFileSync(join(presentationDir, ".gitignore"), "node_modules\ndist\n.slidev\n", "utf-8");
225
- writeFileSync(join(presentationDir, ".npmrc"), "shamefully-hoist=true\n", "utf-8");
226
- }
227
- function createScripts(targetDir) {
228
- writeFileSync(join(join(targetDir, "scripts"), "dev-presentation.mjs"), `#!/usr/bin/env node
229
-
230
- import { existsSync, readdirSync, statSync } from 'node:fs';
231
- import { join, dirname } from 'node:path';
232
- import { fileURLToPath } from 'node:url';
233
- import { spawn } from 'node:child_process';
234
-
235
- const __dirname = dirname(fileURLToPath(import.meta.url));
236
- const rootDir = join(__dirname, '..');
237
- const presentationsDir = join(rootDir, 'presentations');
238
-
239
- function getPresentations() {
240
- if (!existsSync(presentationsDir)) {
241
- return [];
242
- }
243
-
244
- return readdirSync(presentationsDir)
245
- .filter((name) => {
246
- const fullPath = join(presentationsDir, name);
247
- return statSync(fullPath).isDirectory() && existsSync(join(fullPath, 'slides.md'));
248
- })
249
- .sort();
250
- }
251
-
252
- function printUsage(presentations) {
253
- console.error('Usage: pnpm dev <presentation-name>');
254
- console.error('\\nAvailable presentations:');
255
-
256
- if (presentations.length === 0) {
257
- console.error(' No presentations found');
258
- } else {
259
- presentations.forEach((name) => {
260
- console.error(\` \${name}\`);
261
- });
262
- }
263
- }
264
-
265
- function runDev(name) {
266
- const packageName = \`@supaslidev/\${name}\`;
267
-
268
- console.log(\`\\nStarting dev server for \${name}...\\n\`);
269
-
270
- const pnpm = spawn('pnpm', ['--filter', packageName, 'dev'], {
271
- cwd: rootDir,
272
- stdio: 'inherit',
273
- shell: true,
274
- });
275
-
276
- pnpm.on('error', (err) => {
277
- console.error(\`Failed to start dev server: \${err.message}\`);
278
- process.exit(1);
279
- });
280
-
281
- pnpm.on('close', (code) => {
282
- process.exit(code ?? 0);
283
- });
284
- }
285
-
286
- function main() {
287
- const args = process.argv.slice(2);
288
- const name = args[0];
289
- const presentations = getPresentations();
290
-
291
- if (!name) {
292
- console.error('Error: Presentation name is required');
293
- printUsage(presentations);
294
- process.exit(1);
295
- }
296
-
297
- if (!presentations.includes(name)) {
298
- console.error(\`Error: Presentation "\${name}" not found\`);
299
- printUsage(presentations);
300
- process.exit(1);
301
- }
302
-
303
- runDev(name);
304
- }
305
-
306
- main();
307
- `, "utf-8");
215
+ writeFileSync(join(presentationDir, ".gitignore"), "node_modules\n.DS_Store\ndist\n*.local\n.vite-inspect\n.remote-assets\ncomponents.d.ts\n", "utf-8");
308
216
  }
309
217
  function createSharedPackage(targetDir) {
310
218
  const sharedDir = join(targetDir, "packages", "shared");
@@ -326,49 +234,99 @@ function createSharedPackage(targetDir) {
326
234
  keywords: ["slidev-addon", "slidev"],
327
235
  dependencies: { vue: "catalog:" }
328
236
  }, null, 2) + "\n", "utf-8");
329
- writeFileSync(join(sharedDir, "components", "SharedBadge.vue"), `<template>
330
- <span class="shared-badge">
331
- <slot />
332
- </span>
237
+ writeFileSync(join(sharedDir, "components", "SharedBadge.vue"), `<script setup lang="ts">
238
+ defineProps<{
239
+ text?: string;
240
+ }>();
241
+ <\/script>
242
+
243
+ <template>
244
+ <span class="shared-badge">{{ text ?? 'Shared' }}</span>
333
245
  </template>
334
246
 
335
247
  <style scoped>
336
248
  .shared-badge {
337
249
  display: inline-block;
338
- padding: 0.25rem 0.5rem;
339
- border-radius: 0.25rem;
340
- background-color: var(--slidev-theme-primary, #3b82f6);
341
- color: white;
342
- font-size: 0.875rem;
343
- font-weight: 500;
250
+ padding: 0.25rem 0.75rem;
251
+ font-size: 0.75rem;
252
+ font-weight: 600;
253
+ line-height: 1;
254
+ text-transform: uppercase;
255
+ letter-spacing: 0.05em;
256
+ color: #fff;
257
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
258
+ border-radius: 9999px;
344
259
  }
345
260
  </style>
346
261
  `, "utf-8");
347
262
  writeFileSync(join(sharedDir, "README.md"), `# @supaslidev/shared
348
263
 
349
- Shared components, layouts, and styles for your Slidev presentations.
264
+ A local Slidev addon for sharing components, layouts, and styles across all presentations in your workspace.
265
+
266
+ ## How It Works
350
267
 
351
- ## Usage
268
+ This package follows the [Slidev addon pattern](https://sli.dev/guide/write-addon). Slidev automatically discovers and imports resources from the following directories:
352
269
 
353
- This package is configured as a Slidev addon. Components in the \`components\` directory are automatically available in all presentations that include this addon.
270
+ - **components/** - Vue components available in all slides
271
+ - **layouts/** - Custom slide layouts
272
+ - **styles/** - Shared CSS/SCSS styles
354
273
 
355
- ## Structure
274
+ ## Using This Addon
356
275
 
357
- - \`components/\` - Shared Vue components
358
- - \`layouts/\` - Custom slide layouts
359
- - \`styles/\` - Global styles
276
+ Add the addon to your presentation's frontmatter:
277
+
278
+ \`\`\`yaml
279
+ ---
280
+ addons:
281
+ - '@supaslidev/shared'
282
+ ---
283
+ \`\`\`
284
+
285
+ ## Example: Using SharedBadge
286
+
287
+ The \`SharedBadge\` component is available globally once the addon is configured:
288
+
289
+ \`\`\`md
290
+ ---
291
+ addons:
292
+ - '@supaslidev/shared'
293
+ ---
294
+
295
+ # My Slide
296
+
297
+ <SharedBadge text="New" />
298
+ \`\`\`
299
+
300
+ ## Directory Structure
301
+
302
+ \`\`\`
303
+ shared/
304
+ ├── components/ # Vue components (auto-imported)
305
+ │ └── SharedBadge.vue
306
+ ├── layouts/ # Custom layouts
307
+ ├── styles/ # Shared styles
308
+ ├── package.json
309
+ └── README.md
310
+ \`\`\`
311
+
312
+ ## Adding New Components
313
+
314
+ Create a \`.vue\` file in \`components/\`:
315
+
316
+ \`\`\`vue
317
+ <script setup lang="ts">
318
+ defineProps<{
319
+ label: string;
320
+ }>();
321
+ <\/script>
322
+
323
+ <template>
324
+ <div class="my-component">{{ label }}</div>
325
+ </template>
326
+ \`\`\`
327
+
328
+ The component is immediately available in all presentations using this addon.
360
329
  `, "utf-8");
361
- writeFileSync(join(sharedDir, "tsconfig.json"), JSON.stringify({
362
- compilerOptions: {
363
- target: "ESNext",
364
- module: "ESNext",
365
- moduleResolution: "bundler",
366
- strict: true,
367
- jsx: "preserve",
368
- skipLibCheck: true
369
- },
370
- include: ["**/*.ts", "**/*.vue"]
371
- }, null, 2) + "\n", "utf-8");
372
330
  }
373
331
  async function create(options = {}) {
374
332
  const spinner = createSafeSpinner();
@@ -471,8 +429,6 @@ async function create(options = {}) {
471
429
  await createPresentation(targetDir, presentationName);
472
430
  spinner.message("Creating shared package...");
473
431
  createSharedPackage(targetDir);
474
- spinner.message("Creating scripts...");
475
- createScripts(targetDir);
476
432
  spinner.stop("Workspace structure created");
477
433
  if (initGit) {
478
434
  spinner.start("Initializing git repository...");
@@ -514,7 +470,6 @@ async function create(options = {}) {
514
470
  process.exit(1);
515
471
  }
516
472
  }
517
-
518
473
  //#endregion
519
474
  //#region src/state.ts
520
475
  const STATE_DIR = ".supaslidev";
@@ -574,7 +529,6 @@ function findWorkspaceRoot(startDir = process.cwd()) {
574
529
  function getImportedPresentations(workspaceDir) {
575
530
  return readState(workspaceDir)?.importedPresentations ?? [];
576
531
  }
577
-
578
532
  //#endregion
579
533
  //#region src/migrations/manifest.ts
580
534
  const MIGRATIONS_MANIFEST_FILE = "migrations.json";
@@ -627,7 +581,6 @@ function getMigrationOrder(manifest) {
627
581
  for (const migration of manifest.migrations) visit(migration.id, /* @__PURE__ */ new Set());
628
582
  return order;
629
583
  }
630
-
631
584
  //#endregion
632
585
  //#region src/commands/status.ts
633
586
  function getPendingMigrationsCount(workspaceDir) {
@@ -713,7 +666,6 @@ async function status(workspaceDir) {
713
666
  const result = await getStatus(workspaceDir);
714
667
  console.log(formatStatus(result));
715
668
  }
716
-
717
669
  //#endregion
718
670
  //#region src/migrations/backup.ts
719
671
  const BACKUP_DIR = ".supaslidev/backups";
@@ -796,7 +748,6 @@ function deleteBackup(workspaceDir, backupId) {
796
748
  force: true
797
749
  });
798
750
  }
799
-
800
751
  //#endregion
801
752
  //#region src/migrations/journal.ts
802
753
  const JOURNAL_DIR = ".supaslidev";
@@ -836,7 +787,6 @@ function createJournalEntry(migrationId, backupId, success, rolledBack = false,
836
787
  error: error?.message
837
788
  };
838
789
  }
839
-
840
790
  //#endregion
841
791
  //#region src/migrations/runner.ts
842
792
  function loadMigration(migrations, id) {
@@ -1021,7 +971,6 @@ function formatRunOutput(result) {
1021
971
  }
1022
972
  return lines.join("\n");
1023
973
  }
1024
-
1025
974
  //#endregion
1026
975
  //#region src/migrations/loader.ts
1027
976
  const MIGRATIONS = [];
@@ -1049,7 +998,6 @@ async function loadInteractiveMigration(id) {
1049
998
  getAffectedPresentations: entry.module.getAffectedPresentations
1050
999
  };
1051
1000
  }
1052
-
1053
1001
  //#endregion
1054
1002
  //#region src/prompts.ts
1055
1003
  async function promptForCatalogSelection(presentations) {
@@ -1082,7 +1030,6 @@ async function promptForCatalogSelection(presentations) {
1082
1030
  cancelled: false
1083
1031
  };
1084
1032
  }
1085
-
1086
1033
  //#endregion
1087
1034
  //#region src/commands/migrate.ts
1088
1035
  async function getMigrateResult(options = {}) {
@@ -1188,7 +1135,6 @@ async function migrate(options = {}) {
1188
1135
  console.log(formatMigrateOutput(result));
1189
1136
  if (!result.success) process.exit(1);
1190
1137
  }
1191
-
1192
1138
  //#endregion
1193
1139
  //#region src/commands/update.ts
1194
1140
  async function getUpdateResult() {
@@ -1229,7 +1175,6 @@ async function update() {
1229
1175
  console.log(formatUpdateResult(result));
1230
1176
  if (result.error) process.exit(1);
1231
1177
  }
1232
-
1233
1178
  //#endregion
1234
1179
  //#region src/background-update.ts
1235
1180
  function startBackgroundUpdateCheck() {
@@ -1255,7 +1200,6 @@ function printUpdateNotification(latestVersion) {
1255
1200
  console.log(pc.yellow(` Run ${pc.cyan(`npm install -g ${PACKAGE_NAME}`)} to update`));
1256
1201
  console.log(pc.yellow(border));
1257
1202
  }
1258
-
1259
1203
  //#endregion
1260
1204
  //#region src/cli.ts
1261
1205
  const program = new Command();
@@ -1276,11 +1220,9 @@ async function run() {
1276
1220
  startBackgroundUpdateCheck();
1277
1221
  await program.parseAsync();
1278
1222
  }
1279
- const scriptName = process.argv[1] ? basename(process.argv[1]) : "";
1280
- if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href || scriptName === "cli.js") run().catch((err) => {
1223
+ if ((process.argv[1] ? basename(process.argv[1]) : "") === "cli.js") run().catch((err) => {
1281
1224
  console.error(err);
1282
1225
  process.exit(1);
1283
1226
  });
1284
-
1285
1227
  //#endregion
1286
- export { run };
1228
+ export { run };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Command } from "commander";
2
2
  import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
3
3
  import { basename, dirname, join, relative } from "node:path";
4
- import { fileURLToPath, pathToFileURL } from "node:url";
4
+ import { fileURLToPath } from "node:url";
5
5
  import { spawn } from "node:child_process";
6
6
  import * as p from "@clack/prompts";
7
7
  import ejs from "ejs";
@@ -9,11 +9,9 @@ import pc from "picocolors";
9
9
  import { tmpdir } from "node:os";
10
10
  import { parse, parseDocument, stringify } from "yaml";
11
11
  import { IndentationText, Node, Project, SyntaxKind } from "ts-morph";
12
-
12
+ //#endregion
13
13
  //#region src/version.ts
14
- const __dirname = dirname(fileURLToPath(import.meta.url));
15
- const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
16
- const CLI_VERSION = pkg.version;
14
+ const CLI_VERSION = "0.2.1";
17
15
  const PACKAGE_NAME = "@supaslidev/cli";
18
16
  const CACHE_DIR = join(tmpdir(), "supaslidev-cli");
19
17
  const CACHE_FILE = join(CACHE_DIR, "version-cache.json");
@@ -43,11 +41,10 @@ function readCache() {
43
41
  function writeCache(latestVersion) {
44
42
  try {
45
43
  if (!existsSync(CACHE_DIR)) mkdirSync(CACHE_DIR, { recursive: true });
46
- const cache = {
44
+ writeFileSync(CACHE_FILE, JSON.stringify({
47
45
  latestVersion,
48
46
  checkedAt: Date.now()
49
- };
50
- writeFileSync(CACHE_FILE, JSON.stringify(cache));
47
+ }));
51
48
  } catch {}
52
49
  }
53
50
  async function fetchLatestPackageVersion(packageName) {
@@ -86,7 +83,6 @@ function checkForUpdatesCached() {
86
83
  updateAvailable: latestVersion ? compareVersions(CLI_VERSION, latestVersion) : false
87
84
  };
88
85
  }
89
-
90
86
  //#endregion
91
87
  //#region src/create.ts
92
88
  const SUPASLIDEV_FALLBACK_VERSION = "0.1.4";
@@ -158,11 +154,7 @@ async function renderTemplatesRecursively(sourceDir, targetDir, data) {
158
154
  }
159
155
  }
160
156
  function createDirectoryStructure(targetDir) {
161
- for (const dir of [
162
- "presentations",
163
- "packages",
164
- "scripts"
165
- ]) {
157
+ for (const dir of ["presentations", "packages"]) {
166
158
  const fullPath = join(targetDir, dir);
167
159
  mkdirSync(fullPath, { recursive: true });
168
160
  trackPath(fullPath);
@@ -221,90 +213,7 @@ Add your content here
221
213
  [Slidev Documentation](https://sli.dev/)
222
214
  `;
223
215
  writeFileSync(join(presentationDir, "slides.md"), slidesContent, "utf-8");
224
- writeFileSync(join(presentationDir, ".gitignore"), "node_modules\ndist\n.slidev\n", "utf-8");
225
- writeFileSync(join(presentationDir, ".npmrc"), "shamefully-hoist=true\n", "utf-8");
226
- }
227
- function createScripts(targetDir) {
228
- writeFileSync(join(join(targetDir, "scripts"), "dev-presentation.mjs"), `#!/usr/bin/env node
229
-
230
- import { existsSync, readdirSync, statSync } from 'node:fs';
231
- import { join, dirname } from 'node:path';
232
- import { fileURLToPath } from 'node:url';
233
- import { spawn } from 'node:child_process';
234
-
235
- const __dirname = dirname(fileURLToPath(import.meta.url));
236
- const rootDir = join(__dirname, '..');
237
- const presentationsDir = join(rootDir, 'presentations');
238
-
239
- function getPresentations() {
240
- if (!existsSync(presentationsDir)) {
241
- return [];
242
- }
243
-
244
- return readdirSync(presentationsDir)
245
- .filter((name) => {
246
- const fullPath = join(presentationsDir, name);
247
- return statSync(fullPath).isDirectory() && existsSync(join(fullPath, 'slides.md'));
248
- })
249
- .sort();
250
- }
251
-
252
- function printUsage(presentations) {
253
- console.error('Usage: pnpm dev <presentation-name>');
254
- console.error('\\nAvailable presentations:');
255
-
256
- if (presentations.length === 0) {
257
- console.error(' No presentations found');
258
- } else {
259
- presentations.forEach((name) => {
260
- console.error(\` \${name}\`);
261
- });
262
- }
263
- }
264
-
265
- function runDev(name) {
266
- const packageName = \`@supaslidev/\${name}\`;
267
-
268
- console.log(\`\\nStarting dev server for \${name}...\\n\`);
269
-
270
- const pnpm = spawn('pnpm', ['--filter', packageName, 'dev'], {
271
- cwd: rootDir,
272
- stdio: 'inherit',
273
- shell: true,
274
- });
275
-
276
- pnpm.on('error', (err) => {
277
- console.error(\`Failed to start dev server: \${err.message}\`);
278
- process.exit(1);
279
- });
280
-
281
- pnpm.on('close', (code) => {
282
- process.exit(code ?? 0);
283
- });
284
- }
285
-
286
- function main() {
287
- const args = process.argv.slice(2);
288
- const name = args[0];
289
- const presentations = getPresentations();
290
-
291
- if (!name) {
292
- console.error('Error: Presentation name is required');
293
- printUsage(presentations);
294
- process.exit(1);
295
- }
296
-
297
- if (!presentations.includes(name)) {
298
- console.error(\`Error: Presentation "\${name}" not found\`);
299
- printUsage(presentations);
300
- process.exit(1);
301
- }
302
-
303
- runDev(name);
304
- }
305
-
306
- main();
307
- `, "utf-8");
216
+ writeFileSync(join(presentationDir, ".gitignore"), "node_modules\n.DS_Store\ndist\n*.local\n.vite-inspect\n.remote-assets\ncomponents.d.ts\n", "utf-8");
308
217
  }
309
218
  function createSharedPackage(targetDir) {
310
219
  const sharedDir = join(targetDir, "packages", "shared");
@@ -326,49 +235,99 @@ function createSharedPackage(targetDir) {
326
235
  keywords: ["slidev-addon", "slidev"],
327
236
  dependencies: { vue: "catalog:" }
328
237
  }, null, 2) + "\n", "utf-8");
329
- writeFileSync(join(sharedDir, "components", "SharedBadge.vue"), `<template>
330
- <span class="shared-badge">
331
- <slot />
332
- </span>
238
+ writeFileSync(join(sharedDir, "components", "SharedBadge.vue"), `<script setup lang="ts">
239
+ defineProps<{
240
+ text?: string;
241
+ }>();
242
+ <\/script>
243
+
244
+ <template>
245
+ <span class="shared-badge">{{ text ?? 'Shared' }}</span>
333
246
  </template>
334
247
 
335
248
  <style scoped>
336
249
  .shared-badge {
337
250
  display: inline-block;
338
- padding: 0.25rem 0.5rem;
339
- border-radius: 0.25rem;
340
- background-color: var(--slidev-theme-primary, #3b82f6);
341
- color: white;
342
- font-size: 0.875rem;
343
- font-weight: 500;
251
+ padding: 0.25rem 0.75rem;
252
+ font-size: 0.75rem;
253
+ font-weight: 600;
254
+ line-height: 1;
255
+ text-transform: uppercase;
256
+ letter-spacing: 0.05em;
257
+ color: #fff;
258
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
259
+ border-radius: 9999px;
344
260
  }
345
261
  </style>
346
262
  `, "utf-8");
347
263
  writeFileSync(join(sharedDir, "README.md"), `# @supaslidev/shared
348
264
 
349
- Shared components, layouts, and styles for your Slidev presentations.
265
+ A local Slidev addon for sharing components, layouts, and styles across all presentations in your workspace.
266
+
267
+ ## How It Works
268
+
269
+ This package follows the [Slidev addon pattern](https://sli.dev/guide/write-addon). Slidev automatically discovers and imports resources from the following directories:
270
+
271
+ - **components/** - Vue components available in all slides
272
+ - **layouts/** - Custom slide layouts
273
+ - **styles/** - Shared CSS/SCSS styles
350
274
 
351
- ## Usage
275
+ ## Using This Addon
352
276
 
353
- This package is configured as a Slidev addon. Components in the \`components\` directory are automatically available in all presentations that include this addon.
277
+ Add the addon to your presentation's frontmatter:
354
278
 
355
- ## Structure
279
+ \`\`\`yaml
280
+ ---
281
+ addons:
282
+ - '@supaslidev/shared'
283
+ ---
284
+ \`\`\`
356
285
 
357
- - \`components/\` - Shared Vue components
358
- - \`layouts/\` - Custom slide layouts
359
- - \`styles/\` - Global styles
286
+ ## Example: Using SharedBadge
287
+
288
+ The \`SharedBadge\` component is available globally once the addon is configured:
289
+
290
+ \`\`\`md
291
+ ---
292
+ addons:
293
+ - '@supaslidev/shared'
294
+ ---
295
+
296
+ # My Slide
297
+
298
+ <SharedBadge text="New" />
299
+ \`\`\`
300
+
301
+ ## Directory Structure
302
+
303
+ \`\`\`
304
+ shared/
305
+ ├── components/ # Vue components (auto-imported)
306
+ │ └── SharedBadge.vue
307
+ ├── layouts/ # Custom layouts
308
+ ├── styles/ # Shared styles
309
+ ├── package.json
310
+ └── README.md
311
+ \`\`\`
312
+
313
+ ## Adding New Components
314
+
315
+ Create a \`.vue\` file in \`components/\`:
316
+
317
+ \`\`\`vue
318
+ <script setup lang="ts">
319
+ defineProps<{
320
+ label: string;
321
+ }>();
322
+ <\/script>
323
+
324
+ <template>
325
+ <div class="my-component">{{ label }}</div>
326
+ </template>
327
+ \`\`\`
328
+
329
+ The component is immediately available in all presentations using this addon.
360
330
  `, "utf-8");
361
- writeFileSync(join(sharedDir, "tsconfig.json"), JSON.stringify({
362
- compilerOptions: {
363
- target: "ESNext",
364
- module: "ESNext",
365
- moduleResolution: "bundler",
366
- strict: true,
367
- jsx: "preserve",
368
- skipLibCheck: true
369
- },
370
- include: ["**/*.ts", "**/*.vue"]
371
- }, null, 2) + "\n", "utf-8");
372
331
  }
373
332
  async function create(options = {}) {
374
333
  const spinner = createSafeSpinner();
@@ -471,8 +430,6 @@ async function create(options = {}) {
471
430
  await createPresentation(targetDir, presentationName);
472
431
  spinner.message("Creating shared package...");
473
432
  createSharedPackage(targetDir);
474
- spinner.message("Creating scripts...");
475
- createScripts(targetDir);
476
433
  spinner.stop("Workspace structure created");
477
434
  if (initGit) {
478
435
  spinner.start("Initializing git repository...");
@@ -514,7 +471,6 @@ async function create(options = {}) {
514
471
  process.exit(1);
515
472
  }
516
473
  }
517
-
518
474
  //#endregion
519
475
  //#region src/state.ts
520
476
  const STATE_DIR = ".supaslidev";
@@ -610,7 +566,6 @@ function removeImportedPresentation(workspaceDir, name) {
610
566
  state.importedPresentations = state.importedPresentations.filter((p) => p.name !== name);
611
567
  writeState(workspaceDir, state);
612
568
  }
613
-
614
569
  //#endregion
615
570
  //#region src/migrations/manifest.ts
616
571
  const MIGRATIONS_MANIFEST_FILE = "migrations.json";
@@ -672,7 +627,6 @@ function getMigrationOrder(manifest) {
672
627
  for (const migration of manifest.migrations) visit(migration.id, /* @__PURE__ */ new Set());
673
628
  return order;
674
629
  }
675
-
676
630
  //#endregion
677
631
  //#region src/commands/status.ts
678
632
  function getPendingMigrationsCount(workspaceDir) {
@@ -758,7 +712,6 @@ async function status(workspaceDir) {
758
712
  const result = await getStatus(workspaceDir);
759
713
  console.log(formatStatus(result));
760
714
  }
761
-
762
715
  //#endregion
763
716
  //#region src/migrations/backup.ts
764
717
  const BACKUP_DIR = ".supaslidev/backups";
@@ -864,7 +817,6 @@ function getBackupMetadata(workspaceDir, backupId) {
864
817
  function backupExists(workspaceDir, backupId) {
865
818
  return existsSync(join(getBackupPath(workspaceDir, backupId), BACKUP_METADATA_FILE));
866
819
  }
867
-
868
820
  //#endregion
869
821
  //#region src/migrations/journal.ts
870
822
  const JOURNAL_DIR = ".supaslidev";
@@ -925,7 +877,6 @@ function getFailedMigrations(workspaceDir) {
925
877
  function clearJournal(workspaceDir) {
926
878
  writeJournal(workspaceDir, { entries: [] });
927
879
  }
928
-
929
880
  //#endregion
930
881
  //#region src/migrations/runner.ts
931
882
  function loadMigration(migrations, id) {
@@ -1110,7 +1061,6 @@ function formatRunOutput(result) {
1110
1061
  }
1111
1062
  return lines.join("\n");
1112
1063
  }
1113
-
1114
1064
  //#endregion
1115
1065
  //#region src/migrations/loader.ts
1116
1066
  const MIGRATIONS = [];
@@ -1142,7 +1092,6 @@ async function loadInteractiveMigration(id) {
1142
1092
  getAffectedPresentations: entry.module.getAffectedPresentations
1143
1093
  };
1144
1094
  }
1145
-
1146
1095
  //#endregion
1147
1096
  //#region src/prompts.ts
1148
1097
  async function promptForCatalogSelection(presentations) {
@@ -1175,7 +1124,6 @@ async function promptForCatalogSelection(presentations) {
1175
1124
  cancelled: false
1176
1125
  };
1177
1126
  }
1178
-
1179
1127
  //#endregion
1180
1128
  //#region src/commands/migrate.ts
1181
1129
  async function getMigrateResult(options = {}) {
@@ -1281,7 +1229,6 @@ async function migrate(options = {}) {
1281
1229
  console.log(formatMigrateOutput(result));
1282
1230
  if (!result.success) process.exit(1);
1283
1231
  }
1284
-
1285
1232
  //#endregion
1286
1233
  //#region src/commands/update.ts
1287
1234
  async function getUpdateResult() {
@@ -1322,7 +1269,6 @@ async function update() {
1322
1269
  console.log(formatUpdateResult(result));
1323
1270
  if (result.error) process.exit(1);
1324
1271
  }
1325
-
1326
1272
  //#endregion
1327
1273
  //#region src/background-update.ts
1328
1274
  function startBackgroundUpdateCheck() {
@@ -1348,7 +1294,6 @@ function printUpdateNotification(latestVersion) {
1348
1294
  console.log(pc.yellow(` Run ${pc.cyan(`npm install -g ${PACKAGE_NAME}`)} to update`));
1349
1295
  console.log(pc.yellow(border));
1350
1296
  }
1351
-
1352
1297
  //#endregion
1353
1298
  //#region src/cli.ts
1354
1299
  const program = new Command();
@@ -1369,12 +1314,10 @@ async function run$1() {
1369
1314
  startBackgroundUpdateCheck();
1370
1315
  await program.parseAsync();
1371
1316
  }
1372
- const scriptName = process.argv[1] ? basename(process.argv[1]) : "";
1373
- if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href || scriptName === "cli.js") run$1().catch((err) => {
1317
+ if ((process.argv[1] ? basename(process.argv[1]) : "") === "cli.js") run$1().catch((err) => {
1374
1318
  console.error(err);
1375
1319
  process.exit(1);
1376
1320
  });
1377
-
1378
1321
  //#endregion
1379
1322
  //#region src/transformers/json.ts
1380
1323
  function readJsonFile(filePath) {
@@ -1464,7 +1407,6 @@ function mergeJson(target, source) {
1464
1407
  }
1465
1408
  return result;
1466
1409
  }
1467
-
1468
1410
  //#endregion
1469
1411
  //#region src/transformers/yaml.ts
1470
1412
  const defaultParseOptions = { keepSourceTokens: true };
@@ -1543,7 +1485,6 @@ function mergeYaml(target, source) {
1543
1485
  }
1544
1486
  return result;
1545
1487
  }
1546
-
1547
1488
  //#endregion
1548
1489
  //#region src/transformers/typescript.ts
1549
1490
  function createTransformer(filePath) {
@@ -1676,6 +1617,5 @@ function findCallExpression(sourceFile, functionName) {
1676
1617
  if (args.length > 0 && args[0].getKind() === SyntaxKind.ObjectLiteralExpression) return args[0];
1677
1618
  }
1678
1619
  }
1679
-
1680
1620
  //#endregion
1681
- export { addArrayElement, addExport, addImport, addImportedPresentation, addJournalEntry, addMigration, backupExists, clearJournal, createBackup, createEmptyManifest, createInitialState, createJournalEntry, createTransformer, deleteBackup, deleteJsonValue, deleteYamlValue, dryRun, findArrayLiteral, findCallExpression, findDefaultExportObject, findObjectLiteral, findWorkspaceRoot, formatDryRunOutput, formatRunOutput, formatStatus, getBackupMetadata, getFailedMigrations, getImportedPresentations, getJournalEntries, getJsonValue, getLastSuccessfulEntry, getMigrationById, getMigrationHistory, getMigrationOrder, getObjectProperty, getStatus, getYamlValue, hasMigration, initializeState, listBackups, loadInteractiveMigration, loadMigrations, mergeJson, mergeYaml, readJournal, readJsonFile, readManifest, readState, readYamlDocument, readYamlFile, removeArrayElement, removeImport, removeImportedPresentation, removeObjectProperty, restoreBackup, run, run$1 as runCli, setJsonValue, setObjectProperty, setYamlValue, stateExists, status, transformJson, transformTypeScript, transformYaml, transformYamlDocument, updateCliVersion, validateManifest, wasMigrationSuccessful, writeJournal, writeJsonFile, writeManifest, writeState, writeYamlDocument, writeYamlFile };
1621
+ export { addArrayElement, addExport, addImport, addImportedPresentation, addJournalEntry, addMigration, backupExists, clearJournal, createBackup, createEmptyManifest, createInitialState, createJournalEntry, createTransformer, deleteBackup, deleteJsonValue, deleteYamlValue, dryRun, findArrayLiteral, findCallExpression, findDefaultExportObject, findObjectLiteral, findWorkspaceRoot, formatDryRunOutput, formatRunOutput, formatStatus, getBackupMetadata, getFailedMigrations, getImportedPresentations, getJournalEntries, getJsonValue, getLastSuccessfulEntry, getMigrationById, getMigrationHistory, getMigrationOrder, getObjectProperty, getStatus, getYamlValue, hasMigration, initializeState, listBackups, loadInteractiveMigration, loadMigrations, mergeJson, mergeYaml, readJournal, readJsonFile, readManifest, readState, readYamlDocument, readYamlFile, removeArrayElement, removeImport, removeImportedPresentation, removeObjectProperty, restoreBackup, run, run$1 as runCli, setJsonValue, setObjectProperty, setYamlValue, stateExists, status, transformJson, transformTypeScript, transformYaml, transformYamlDocument, updateCliVersion, validateManifest, wasMigrationSuccessful, writeJournal, writeJsonFile, writeManifest, writeState, writeYamlDocument, writeYamlFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-supaslidev",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "CLI tool for scaffolding Supaslidev presentations",
5
5
  "keywords": [
6
6
  "slidev",
@@ -47,10 +47,10 @@
47
47
  "devDependencies": {
48
48
  "@types/ejs": "^3.1.5",
49
49
  "@types/node": "^22.10.0",
50
- "tsdown": "^0.12.5",
50
+ "tsdown": "^0.21.6",
51
51
  "tsx": "^4.19.0",
52
52
  "typescript": "^5.3.3",
53
- "vitest": "^3.0.0"
53
+ "vitest": "^4.0.0"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsdown",
@@ -4,4 +4,3 @@ deploy
4
4
  .DS_Store
5
5
  *.log
6
6
  .slidev
7
- .turbo
@@ -0,0 +1,3 @@
1
+ import { defineSupaslidevConfig } from 'supaslidev';
2
+
3
+ export default defineNuxtConfig(defineSupaslidevConfig({}));
@@ -9,9 +9,11 @@
9
9
  "new": "supaslidev new",
10
10
  "present": "supaslidev present",
11
11
  "export": "supaslidev export",
12
- "deploy": "supaslidev deploy"
12
+ "deploy": "supaslidev deploy",
13
+ "build": "pnpm --filter @supaslidev/* run build"
13
14
  },
14
15
  "devDependencies": {
16
+ "nuxt": "catalog:core",
15
17
  "playwright-chromium": "catalog:",
16
18
  "supaslidev": "<%= supaslidevVersion %>"
17
19
  },
@@ -8,7 +8,27 @@ catalog:
8
8
  '@slidev/theme-seriph': latest
9
9
  '@slidev/theme-apple-basic': latest
10
10
  vue: ^3.5.26
11
- '@vue/compiler-sfc': ^3.5.27
12
- typescript: ^5.3.3
13
- vue-tsc: ^2.0.0
14
11
  playwright-chromium: ^1.58.2
12
+
13
+ catalogs:
14
+ core:
15
+ nuxt: ^4.4.2
16
+ '@vue/compiler-sfc': ^3.5.27
17
+ typescript: ^5.3.3
18
+ vue-tsc: ^2.0.0
19
+
20
+ catalogMode: prefer
21
+
22
+ linkWorkspacePackages: true
23
+
24
+ shellEmulator: true
25
+
26
+ trustPolicy: no-downgrade
27
+
28
+ trustPolicyExclude:
29
+ - axios
30
+ - chokidar
31
+ - semver
32
+ - undici
33
+ - undici-types
34
+ - vite
@@ -1 +0,0 @@
1
- shamefully-hoist=true
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "strict": true,
7
- "jsx": "preserve",
8
- "resolveJsonModule": true,
9
- "isolatedModules": true,
10
- "esModuleInterop": true,
11
- "lib": ["ESNext", "DOM"],
12
- "skipLibCheck": true,
13
- "noEmit": true
14
- },
15
- "include": ["packages/**/*.ts", "packages/**/*.vue"],
16
- "exclude": ["node_modules", "**/dist"]
17
- }
@@ -1,24 +0,0 @@
1
- {
2
- "$schema": "https://turbo.build/schema.json",
3
- "tasks": {
4
- "typecheck": {
5
- "dependsOn": ["^typecheck"],
6
- "inputs": ["**/*.ts", "**/*.tsx", "**/*.vue", "tsconfig.json"],
7
- "outputs": []
8
- },
9
- "lint": {
10
- "dependsOn": ["^lint"],
11
- "inputs": ["**/*.ts", "**/*.tsx", "**/*.vue", "**/*.js", "**/*.mjs"],
12
- "outputs": []
13
- },
14
- "build": {
15
- "dependsOn": ["^build"],
16
- "inputs": ["src/**", "**/*.ts", "**/*.vue", "package.json"],
17
- "outputs": ["dist/**"]
18
- },
19
- "dev": {
20
- "cache": false,
21
- "persistent": true
22
- }
23
- }
24
- }