diff --git a/docs/content/spark/examples.mdx b/docs/content/spark/examples.mdx index 8dd97de..29909ac 100644 --- a/docs/content/spark/examples.mdx +++ b/docs/content/spark/examples.mdx @@ -31,10 +31,10 @@ Kitchen Sink demonstrates windows/geometry, menus/shortcuts, files/dialogs, stre Create a focused app with npm: ```sh -npm create @legendapp/spark@latest MyNotes -- --example notes-lite -npm create @legendapp/spark@latest MyMusic -- --example music-lite -npm create @legendapp/spark@latest MyDiff -- --example diff-lite -npm create @legendapp/spark@latest MyEditor -- --example document-editor +npm create @legendapp/spark@next MyNotes -- --example notes-lite +npm create @legendapp/spark@next MyMusic -- --example music-lite +npm create @legendapp/spark@next MyDiff -- --example diff-lite +npm create @legendapp/spark@next MyEditor -- --example document-editor ``` Then run the generated app, for example: diff --git a/docs/content/spark/getting-started.mdx b/docs/content/spark/getting-started.mdx index d9357a7..ce59cb4 100644 --- a/docs/content/spark/getting-started.mdx +++ b/docs/content/spark/getting-started.mdx @@ -18,7 +18,7 @@ Creating an app and running it with Spark Runner does not require Xcode or Cocoa Create an app with npm: ```sh -npm create @legendapp/spark@latest MyApp +npm create @legendapp/spark@next MyApp cd MyApp ``` @@ -27,15 +27,21 @@ The command runs `@legendapp/create-spark`, which creates the app and installs i Other package managers: ```sh -bunx @legendapp/create-spark MyApp -pnpm create @legendapp/spark MyApp -yarn create @legendapp/spark MyApp +bun create @legendapp/spark@next MyApp +pnpm create @legendapp/spark@next MyApp +yarn create @legendapp/spark@next MyApp # Yarn 2+ +``` + +For Yarn Classic (1.x), use npm to run the tagged creator and select Yarn for installation: + +```sh +npm create @legendapp/spark@next MyApp -- --package-manager yarn ``` To choose a package manager, pass `--package-manager npm|pnpm|yarn|bun`. For example: ```sh -npm create @legendapp/spark@latest MyApp -- --package-manager pnpm +npm create @legendapp/spark@next MyApp -- --package-manager pnpm ``` The chosen manager must be installed. The commands below use npm; use your chosen manager's `run` command instead if needed. Keep the generated lockfile and `spark-packages/` archives in version control so other machines can reinstall the same inputs. diff --git a/docs/scripts/spark-creation.test.ts b/docs/scripts/spark-creation.test.ts new file mode 100644 index 0000000..06366a8 --- /dev/null +++ b/docs/scripts/spark-creation.test.ts @@ -0,0 +1,38 @@ +import { expect, test } from 'bun:test'; +import { readFileSync, readdirSync } from 'node:fs'; +import path from 'node:path'; + +const docs = path.resolve(import.meta.dirname, '..'); +const content = path.join(docs, 'content/spark'); +const landing = 'src/components/site/framework-landing.tsx'; +const read = (file: string) => readFileSync(path.join(docs, file), 'utf8'); + +test('every Spark registry creation command uses the next creator', () => { + const files = readdirSync(content, { recursive: true, encoding: 'utf8' }) + .filter((file) => file.endsWith('.mdx')).map((file) => `content/spark/${file}`); + let commands = 0; + for (const file of [...files, landing]) { + const pattern = /\b(npm create|bun create|pnpm create|yarn create|npx|bunx|pnpm dlx|yarn dlx)\s+(@legendapp\/(?:create-)?spark(?:@[^\s'"`\\]+)?)/g; + for (const match of read(file).matchAll(pattern)) { + commands++; + const creator = match[1].endsWith('create') ? '@legendapp/spark@next' : '@legendapp/create-spark@next'; + expect({ file, package: match[2] }).toEqual({ file, package: creator }); + } + } + expect(commands).toBeGreaterThan(0); +}); + +test('Spark onboarding keeps package manager variants, examples, and landing next steps', () => { + const gettingStarted = read('content/spark/getting-started.mdx'); + for (const manager of ['npm', 'bun', 'pnpm', 'yarn']) { + expect(gettingStarted).toContain(`${manager} create @legendapp/spark@next MyApp`); + } + expect(gettingStarted).toContain('yarn create @legendapp/spark@next MyApp # Yarn 2+'); + expect(gettingStarted).toContain('For Yarn Classic (1.x)'); + expect(gettingStarted).toContain('npm create @legendapp/spark@next MyApp -- --package-manager yarn'); + const examples = read('content/spark/examples.mdx'); + for (const [app, example] of [['MyNotes', 'notes-lite'], ['MyMusic', 'music-lite'], ['MyDiff', 'diff-lite'], ['MyEditor', 'document-editor']]) { + expect(examples).toContain(`npm create @legendapp/spark@next ${app} -- --example ${example}`); + } + expect(read(landing)).toContain('npm create @legendapp/spark@next MyApp\\ncd MyApp\\nnpm run macos'); +}); diff --git a/docs/src/components/site/framework-landing.tsx b/docs/src/components/site/framework-landing.tsx index 791184c..6a278fb 100644 --- a/docs/src/components/site/framework-landing.tsx +++ b/docs/src/components/site/framework-landing.tsx @@ -41,7 +41,7 @@ const runtimes = [ label: 'Spark Runner', title: 'Start without Xcode', text: 'A prebuilt development app. Create a project, run it, and edit App.tsx with Fast Refresh.', - code: 'npx @legendapp/spark@next create MyApp\ncd MyApp\nnpm run macos', + code: 'npm create @legendapp/spark@next MyApp\ncd MyApp\nnpm run macos', }, { label: 'Custom development build',