Skip to content

Commit 01dfd9b

Browse files
authored
Merge branch 'sveltejs:main' into fix-paraglide-addons
2 parents 4f5db1a + c6c0dd5 commit 01dfd9b

File tree

22 files changed

+262
-447
lines changed

22 files changed

+262
-447
lines changed

.changeset/move-file-helpers.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/sv-utils': patch
3+
'sv': patch
4+
---
5+
6+
refactor: move files utilities to `@sveltejs/sv-utils`

.changeset/twenty-knives-read.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'sv': patch
3+
---
4+
5+
chore: add text-scale meta in html
Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import * as p from '@clack/prompts';
2-
import { type AgentName, resolveCommand, parse } from '@sveltejs/sv-utils';
31
import fs from 'node:fs';
42
import path from 'node:path';
5-
import { exec } from 'tinyexec';
6-
import type { Workspace } from './workspace.ts';
3+
import { parseJson } from './tooling/parsers.ts';
74

85
export type Package = {
96
name: string;
@@ -27,41 +24,10 @@ export function getPackageJson(cwd: string): {
2724
throw new Error(`Invalid workspace: missing '${pkgPath}'`);
2825
}
2926

30-
const { data, generateCode } = parse.json(packageText);
27+
const { data, generateCode } = parseJson(packageText);
3128
return { source: packageText, data: data as Package, generateCode };
3229
}
3330

34-
export async function formatFiles(options: {
35-
packageManager: AgentName;
36-
cwd: string;
37-
filesToFormat: string[];
38-
}): Promise<void> {
39-
if (options.filesToFormat.length === 0) return;
40-
const { start, stop } = p.spinner();
41-
start('Formatting modified files');
42-
43-
const args = ['prettier', '--write', '--ignore-unknown', ...options.filesToFormat];
44-
const cmd = resolveCommand(options.packageManager, 'execute-local', args)!;
45-
46-
try {
47-
const result = await exec(cmd.command, cmd.args, {
48-
nodeOptions: { cwd: options.cwd, stdio: 'pipe' },
49-
throwOnError: true
50-
});
51-
if (result.exitCode !== 0) {
52-
stop('Failed to format files');
53-
p.log.error(result.stderr);
54-
return;
55-
}
56-
} catch (e) {
57-
stop('Failed to format files');
58-
// @ts-expect-error
59-
p.log.error(e?.output?.stderr || 'unknown error');
60-
return;
61-
}
62-
stop('Successfully formatted modified files');
63-
}
64-
6531
export function readFile(cwd: string, filePath: string): string {
6632
const fullFilePath = path.resolve(cwd, filePath);
6733

@@ -74,11 +40,29 @@ export function readFile(cwd: string, filePath: string): string {
7440
return text;
7541
}
7642

43+
export function fileExists(cwd: string, filePath: string): boolean {
44+
const fullFilePath = path.resolve(cwd, filePath);
45+
return fs.existsSync(fullFilePath);
46+
}
47+
48+
export function writeFile(cwd: string, filePath: string, content: string): void {
49+
const fullFilePath = path.resolve(cwd, filePath);
50+
const fullDirectoryPath = path.dirname(fullFilePath);
51+
52+
if (content && !content.endsWith('\n')) content += '\n';
53+
54+
if (!fs.existsSync(fullDirectoryPath)) {
55+
fs.mkdirSync(fullDirectoryPath, { recursive: true });
56+
}
57+
58+
fs.writeFileSync(fullFilePath, content, 'utf8');
59+
}
60+
7761
export function installPackages(
7862
dependencies: Array<{ pkg: string; version: string; dev: boolean }>,
79-
workspace: Workspace
63+
cwd: string
8064
): string {
81-
const { data, generateCode } = getPackageJson(workspace.cwd);
65+
const { data, generateCode } = getPackageJson(cwd);
8266

8367
for (const dependency of dependencies) {
8468
if (dependency.dev) {
@@ -93,7 +77,7 @@ export function installPackages(
9377
if (data.dependencies) data.dependencies = alphabetizeProperties(data.dependencies);
9478
if (data.devDependencies) data.devDependencies = alphabetizeProperties(data.devDependencies);
9579

96-
writeFile(workspace, commonFilePaths.packageJson, generateCode());
80+
writeFile(cwd, commonFilePaths.packageJson, generateCode());
9781
return commonFilePaths.packageJson;
9882
}
9983

@@ -106,24 +90,6 @@ function alphabetizeProperties(obj: Record<string, string>) {
10690
return orderedObj;
10791
}
10892

109-
export function writeFile(workspace: Workspace, filePath: string, content: string): void {
110-
const fullFilePath = path.resolve(workspace.cwd, filePath);
111-
const fullDirectoryPath = path.dirname(fullFilePath);
112-
113-
if (content && !content.endsWith('\n')) content += '\n';
114-
115-
if (!fs.existsSync(fullDirectoryPath)) {
116-
fs.mkdirSync(fullDirectoryPath, { recursive: true });
117-
}
118-
119-
fs.writeFileSync(fullFilePath, content, 'utf8');
120-
}
121-
122-
export function fileExists(cwd: string, filePath: string): boolean {
123-
const fullFilePath = path.resolve(cwd, filePath);
124-
return fs.existsSync(fullFilePath);
125-
}
126-
12793
export const commonFilePaths = {
12894
packageJson: 'package.json',
12995
svelteConfig: 'svelte.config.js',

packages/sv-utils/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ export { createPrinter } from './utils.ts';
6161
export { sanitizeName } from './sanitize.ts';
6262
export { downloadJson } from './downloadJson.ts';
6363

64+
// File system helpers
65+
export {
66+
commonFilePaths,
67+
fileExists,
68+
getPackageJson,
69+
installPackages,
70+
readFile,
71+
writeFile,
72+
type Package
73+
} from './files.ts';
74+
6475
// Terminal styling
6576
export { color } from './color.ts';
6677

packages/sv/src/addons/drizzle.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
1-
import { color, dedent, text, js, parse, resolveCommand, json } from '@sveltejs/sv-utils';
1+
import {
2+
color,
3+
dedent,
4+
text,
5+
js,
6+
parse,
7+
resolveCommand,
8+
json,
9+
fileExists
10+
} from '@sveltejs/sv-utils';
211
import crypto from 'node:crypto';
312
import fs from 'node:fs';
413
import path from 'node:path';
514
import { defineAddon, defineAddonOptions } from '../core/config.ts';
6-
import { fileExists } from '../core/files.ts';
715
import type { OptionValues } from '../core/options.ts';
816
import { getNodeTypesVersion } from './common.ts';
917

packages/sv/src/addons/sveltekit-adapter.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
import { color, js, resolveCommand, json, sanitizeName, text, parse } from '@sveltejs/sv-utils';
1+
import {
2+
color,
3+
js,
4+
resolveCommand,
5+
json,
6+
sanitizeName,
7+
text,
8+
parse,
9+
fileExists
10+
} from '@sveltejs/sv-utils';
211
import { readFileSync } from 'node:fs';
312
import { join } from 'node:path';
413
import { defineAddon, defineAddonOptions } from '../core/config.ts';
5-
import { fileExists } from '../core/files.ts';
614

715
const adapters = [
816
{ id: 'auto', package: '@sveltejs/adapter-auto', version: '^7.0.0' },
Lines changed: 3 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -1,117 +1,4 @@
1-
import { chromium } from '@playwright/test';
2-
import { execSync } from 'node:child_process';
3-
import fs from 'node:fs';
4-
import path from 'node:path';
5-
import { add } from 'sv';
6-
import {
7-
createProject,
8-
addPnpmBuildDependencies,
9-
prepareServer,
10-
type AddonTestCase,
11-
type Fixtures,
12-
type SetupTestOptions
13-
} from 'sv/testing';
14-
import { inject, test as vitestTest, beforeAll, beforeEach } from 'vitest';
15-
import type { AddonMap } from '../../../core/engine.ts';
1+
import * as vitest from 'vitest';
2+
import { createSetupTest } from '../../../testing.ts';
163

17-
const cwd = inject('testDir');
18-
const templatesDir = inject('templatesDir');
19-
const variants = inject('variants');
20-
21-
export function setupTest<Addons extends AddonMap>(
22-
addons: Addons,
23-
options?: SetupTestOptions<Addons>
24-
) {
25-
const test = vitestTest.extend<Fixtures>({} as any);
26-
27-
const withBrowser = options?.browser ?? true;
28-
29-
let create: ReturnType<typeof createProject>;
30-
let browser: Awaited<ReturnType<typeof chromium.launch>>;
31-
32-
if (withBrowser) {
33-
beforeAll(async () => {
34-
browser = await chromium.launch();
35-
return async () => {
36-
await browser.close();
37-
};
38-
});
39-
}
40-
41-
const testCases: Array<AddonTestCase<Addons>> = [];
42-
for (const kind of options?.kinds ?? []) {
43-
for (const variant of variants) {
44-
const addonTestCase = { variant, kind };
45-
if (options?.filter === undefined || options.filter(addonTestCase)) {
46-
testCases.push(addonTestCase);
47-
}
48-
}
49-
}
50-
let testName: string;
51-
test.beforeAll(async (_ctx, suite) => {
52-
testName = path.dirname(suite.file.filepath).split('/').at(-1)!;
53-
54-
// constructs a builder to create test projects
55-
create = createProject({ cwd, templatesDir, testName });
56-
57-
// creates a pnpm workspace in each addon dir
58-
fs.writeFileSync(
59-
path.resolve(cwd, testName, 'pnpm-workspace.yaml'),
60-
"packages:\n - '**/*'",
61-
'utf8'
62-
);
63-
64-
// creates a barebones package.json in each addon dir
65-
fs.writeFileSync(
66-
path.resolve(cwd, testName, 'package.json'),
67-
JSON.stringify({
68-
name: `${testName}-workspace-root`,
69-
private: true
70-
})
71-
);
72-
73-
for (const addonTestCase of testCases) {
74-
const { variant, kind } = addonTestCase;
75-
const cwd = create({ testId: `${kind.type}-${variant}`, variant });
76-
77-
// test metadata
78-
const metaPath = path.resolve(cwd, 'meta.json');
79-
fs.writeFileSync(metaPath, JSON.stringify({ variant, kind }, null, '\t'), 'utf8');
80-
81-
if (options?.preAdd) {
82-
await options.preAdd({ addonTestCase, cwd });
83-
}
84-
const { pnpmBuildDependencies } = await add({
85-
cwd,
86-
addons,
87-
options: kind.options,
88-
packageManager: 'pnpm'
89-
});
90-
await addPnpmBuildDependencies(cwd, 'pnpm', ['esbuild', ...pnpmBuildDependencies]);
91-
}
92-
93-
execSync('pnpm install', { cwd: path.resolve(cwd, testName), stdio: 'pipe' });
94-
});
95-
96-
// runs before each test case
97-
beforeEach<Fixtures>(async (ctx) => {
98-
let browserCtx: Awaited<ReturnType<typeof browser.newContext>>;
99-
if (withBrowser) {
100-
browserCtx = await browser.newContext();
101-
ctx.page = await browserCtx.newPage();
102-
}
103-
104-
ctx.cwd = (addonTestCase) => {
105-
return path.join(cwd, testName, `${addonTestCase.kind.type}-${addonTestCase.variant}`);
106-
};
107-
108-
return async () => {
109-
if (withBrowser) {
110-
await browserCtx.close();
111-
}
112-
// ...other tear downs
113-
};
114-
});
115-
116-
return { test, testCases, prepareServer };
117-
}
4+
export const setupTest = createSetupTest(vitest);

packages/sv/src/cli/add.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
} from '../core/config.ts';
2121
import { applyAddons, setupAddons } from '../core/engine.ts';
2222
import { downloadPackage, getPackageJSON } from '../core/fetch-packages.ts';
23-
import { formatFiles } from '../core/files.ts';
23+
import { formatFiles } from '../core/formatFiles.ts';
2424
import {
2525
AGENT_NAMES,
2626
addPnpmBuildDependencies,

packages/sv/src/cli/create.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as p from '@clack/prompts';
2-
import { color, resolveCommand } from '@sveltejs/sv-utils';
2+
import { color, resolveCommand, commonFilePaths, getPackageJson } from '@sveltejs/sv-utils';
33
import { Command, Option } from 'commander';
44
import fs from 'node:fs';
55
import path from 'node:path';
66
import process from 'node:process';
77
import * as v from 'valibot';
88
import * as common from '../core/common.ts';
99
import type { LoadedAddon, OptionValues } from '../core/config.ts';
10-
import { commonFilePaths, formatFiles, getPackageJson } from '../core/files.ts';
10+
import { formatFiles } from '../core/formatFiles.ts';
1111
import {
1212
AGENT_NAMES,
1313
addPnpmBuildDependencies,

0 commit comments

Comments
 (0)