diff --git a/packages/ast-tooling/README.md b/packages/ast-tooling/README.md deleted file mode 100644 index 7f3a2c381..000000000 --- a/packages/ast-tooling/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @sveltejs/ast-tooling - -This package provides tools and methods for parsing and serializing CSS, HTML and JS AST's. As the main [sv](https://svelte-add.com) project requires all of these tools they have been extracted into this separate project. - -Additionally this separate package allows us to bundle all (currently 8) required dependencies into on single package. diff --git a/packages/ast-tooling/package.json b/packages/ast-tooling/package.json deleted file mode 100644 index ee7629ce5..000000000 --- a/packages/ast-tooling/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@sveltejs/ast-tooling", - "private": true, - "version": "0.0.0", - "type": "module", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/sveltejs/cli/tree/main/packages/ast-tooling" - }, - "bugs": "https://github.com/sveltejs/cli/issues", - "scripts": { - "check": "tsc", - "format": "pnpm lint --write", - "lint": "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore" - }, - "files": [ - "dist" - ], - "exports": { - ".": { - "types": "./dist/index.d.ts", - "default": "./dist/index.js" - } - }, - "devDependencies": { - "@sveltejs/acorn-typescript": "^1.0.1", - "@types/estree": "^1.0.6", - "acorn": "^8.14.0", - "dedent": "^1.5.3", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "esrap": "^1.4.5", - "htmlparser2": "^9.1.0", - "postcss": "^8.4.49", - "silver-fleece": "^1.2.1", - "zimmerframe": "^1.1.2" - } -} diff --git a/packages/ast-tooling/tsconfig.json b/packages/ast-tooling/tsconfig.json deleted file mode 100644 index c98d2852d..000000000 --- a/packages/ast-tooling/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "checkJs": false, - "isolatedDeclarations": true, - "declaration": true - }, - "exclude": ["vitest.config.ts"] -} diff --git a/packages/ast-tooling/utils.ts b/packages/ast-tooling/utils.ts deleted file mode 100644 index b101faab8..000000000 --- a/packages/ast-tooling/utils.ts +++ /dev/null @@ -1,72 +0,0 @@ -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; - -// Sourced from `golden-fleece` -// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 -export function guessIndentString(str: string | undefined): string { - if (!str) return '\t'; - - const lines = str.split('\n'); - - let tabs = 0; - let spaces = 0; - let minSpaces = 8; - - lines.forEach((line) => { - const match = /^(?: +|\t+)/.exec(line); - if (!match) return; - - const whitespace = match[0]; - if (whitespace.length === line.length) return; - - if (whitespace[0] === '\t') { - tabs += 1; - } else { - spaces += 1; - if (whitespace.length > 1 && whitespace.length < minSpaces) { - minSpaces = whitespace.length; - } - } - }); - - if (spaces > tabs) { - let result = ''; - while (minSpaces--) result += ' '; - return result; - } else { - return '\t'; - } -} - -export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { - let singleCount = 0; - let doubleCount = 0; - - Walker.walk(ast, null, { - Literal(node) { - if (node.raw && node.raw.length >= 2) { - // we have at least two characters in the raw string that could represent both quotes - const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; - for (const quote of quotes) { - switch (quote) { - case "'": - singleCount++; - break; - case '"': - doubleCount++; - break; - default: - break; - } - } - } - } - }); - - if (singleCount === 0 && doubleCount === 0) { - // new file or file without any quotes - return undefined; - } - - return singleCount > doubleCount ? 'single' : 'double'; -} diff --git a/packages/ast-tooling/vitest.config.ts b/packages/ast-tooling/vitest.config.ts deleted file mode 100644 index 01f7288b8..000000000 --- a/packages/ast-tooling/vitest.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineProject } from 'vitest/config'; - -export default defineProject({ - test: { - name: 'ast-tooling', - include: ['./tests/*.ts'] - } -}); diff --git a/packages/core/index.ts b/packages/core/index.ts index 9ba5b0863..e68a90e8a 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -9,4 +9,4 @@ export type * from './addon/options.ts'; export type * from './addon/config.ts'; export type * from './addon/workspace.ts'; -export { Walker } from '@sveltejs/ast-tooling'; +export { Walker } from './tooling/index.ts'; diff --git a/packages/core/package.json b/packages/core/package.json index 4de33a4b5..507fa17de 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,15 +41,23 @@ "default": "./dist/parsers.js" } }, - "dependencies": { - "@sveltejs/ast-tooling": "workspace:*" - }, "devDependencies": { + "@sveltejs/acorn-typescript": "^1.0.1", "@sveltejs/clack-prompts": "workspace:*", + "@types/estree": "^1.0.6", + "acorn": "^8.14.0", "decircular": "^1.0.0", "dedent": "^1.5.3", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "esrap": "^1.4.5", + "htmlparser2": "^9.1.0", "magic-string": "^0.30.15", - "picocolors": "^1.1.1" + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "silver-fleece": "^1.2.1", + "zimmerframe": "^1.1.2" }, "keywords": [ "create", diff --git a/packages/core/tests/css/index.ts b/packages/core/tests/css/index.ts index d9d20386d..6548abf77 100644 --- a/packages/core/tests/css/index.ts +++ b/packages/core/tests/css/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseCss, serializeCss } from '@sveltejs/ast-tooling'; +import { parseCss, serializeCss } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/html/index.ts b/packages/core/tests/html/index.ts index b5e33cd35..d327848b2 100644 --- a/packages/core/tests/html/index.ts +++ b/packages/core/tests/html/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseHtml, serializeHtml } from '@sveltejs/ast-tooling'; +import { parseHtml, serializeHtml } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/core/tests/js/index.ts b/packages/core/tests/js/index.ts index 6bcfda9f5..bc6a37b18 100644 --- a/packages/core/tests/js/index.ts +++ b/packages/core/tests/js/index.ts @@ -3,7 +3,7 @@ import { join, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; import prettier from 'prettier'; import { describe, expect, test } from 'vitest'; -import { parseScript, serializeScript } from '@sveltejs/ast-tooling'; +import { parseScript, serializeScript } from '../../tooling/index.ts'; const baseDir = resolve(fileURLToPath(import.meta.url), '..'); const categoryDirectories = getDirectoryNames(baseDir); diff --git a/packages/ast-tooling/tests/utils.ts b/packages/core/tests/utils.ts similarity index 95% rename from packages/ast-tooling/tests/utils.ts rename to packages/core/tests/utils.ts index fd65346d5..a2a4405b8 100644 --- a/packages/ast-tooling/tests/utils.ts +++ b/packages/core/tests/utils.ts @@ -1,7 +1,12 @@ import { expect, test } from 'vitest'; import dedent from 'dedent'; -import { guessIndentString, guessQuoteStyle } from '../utils.ts'; -import { parseScript, serializeScript, type AstTypes } from '../index.ts'; +import { + parseScript, + serializeScript, + guessIndentString, + guessQuoteStyle, + type AstTypes +} from '../tooling/index.ts'; test('guessIndentString - one tab', () => { const code = dedent` diff --git a/packages/core/tooling/css/index.ts b/packages/core/tooling/css/index.ts index f3a460ca4..ab69813e6 100644 --- a/packages/core/tooling/css/index.ts +++ b/packages/core/tooling/css/index.ts @@ -1,11 +1,4 @@ -import { - Declaration, - Rule, - AtRule, - Comment, - type CssAst, - type CssChildNode -} from '@sveltejs/ast-tooling'; +import { Declaration, Rule, AtRule, Comment, type CssAst, type CssChildNode } from '../index.ts'; export type { CssAst }; diff --git a/packages/core/tooling/html/index.ts b/packages/core/tooling/html/index.ts index a02e689aa..94dcd881e 100644 --- a/packages/core/tooling/html/index.ts +++ b/packages/core/tooling/html/index.ts @@ -5,7 +5,7 @@ import { HtmlElement, HtmlElementType, parseHtml -} from '@sveltejs/ast-tooling'; +} from '../index.ts'; import { addFromString } from '../js/common.ts'; export { HtmlElement, HtmlElementType }; diff --git a/packages/ast-tooling/index.ts b/packages/core/tooling/index.ts similarity index 72% rename from packages/ast-tooling/index.ts rename to packages/core/tooling/index.ts index f7ac628c5..27e41cbe3 100644 --- a/packages/ast-tooling/index.ts +++ b/packages/core/tooling/index.ts @@ -1,3 +1,5 @@ +import * as Walker from 'zimmerframe'; +import type { TsEstree } from './js/ts-estree.ts'; import { Document, Element, type ChildNode } from 'domhandler'; import { ElementType, parseDocument } from 'htmlparser2'; import serializeDom from 'dom-serializer'; @@ -11,21 +13,10 @@ import { type ChildNode as CssChildNode } from 'postcss'; import * as fleece from 'silver-fleece'; -import * as Walker from 'zimmerframe'; -import type { TsEstree } from './ts-estree.ts'; -import { guessIndentString, guessQuoteStyle } from './utils.ts'; import { print as esrapPrint } from 'esrap'; import * as acorn from 'acorn'; import { tsPlugin } from '@sveltejs/acorn-typescript'; -/** - * Most of the AST tooling is pretty big in bundle size and bundling takes forever. - * Nevertheless bundling of these tools seems smart, as they add many dependencies to each install. - * In order to avoid long bundling during development, all of the AST tools have been extracted - * into this separate package and are bundled only here. This package has been marked as external - * and will not be bundled into all other projects / bundles. - */ - export { // html Document as HtmlDocument, @@ -179,3 +170,73 @@ export function serializeJson(originalInput: string, data: unknown): string { return fleece.stringify(data, { spaces }); } + +// Sourced from `golden-fleece` +// https://github.com/Rich-Harris/golden-fleece/blob/f2446f331640f325e13609ed99b74b6a45e755c2/src/patch.ts#L302 +export function guessIndentString(str: string | undefined): string { + if (!str) return '\t'; + + const lines = str.split('\n'); + + let tabs = 0; + let spaces = 0; + let minSpaces = 8; + + lines.forEach((line) => { + const match = /^(?: +|\t+)/.exec(line); + if (!match) return; + + const whitespace = match[0]; + if (whitespace.length === line.length) return; + + if (whitespace[0] === '\t') { + tabs += 1; + } else { + spaces += 1; + if (whitespace.length > 1 && whitespace.length < minSpaces) { + minSpaces = whitespace.length; + } + } + }); + + if (spaces > tabs) { + let result = ''; + while (minSpaces--) result += ' '; + return result; + } else { + return '\t'; + } +} + +export function guessQuoteStyle(ast: TsEstree.Node): 'single' | 'double' | undefined { + let singleCount = 0; + let doubleCount = 0; + + Walker.walk(ast, null, { + Literal(node) { + if (node.raw && node.raw.length >= 2) { + // we have at least two characters in the raw string that could represent both quotes + const quotes = [node.raw[0], node.raw[node.raw.length - 1]]; + for (const quote of quotes) { + switch (quote) { + case "'": + singleCount++; + break; + case '"': + doubleCount++; + break; + default: + break; + } + } + } + } + }); + + if (singleCount === 0 && doubleCount === 0) { + // new file or file without any quotes + return undefined; + } + + return singleCount > doubleCount ? 'single' : 'double'; +} diff --git a/packages/core/tooling/js/array.ts b/packages/core/tooling/js/array.ts index 1565d10a5..46da53ee7 100644 --- a/packages/core/tooling/js/array.ts +++ b/packages/core/tooling/js/array.ts @@ -1,5 +1,5 @@ import { areNodesEqual } from './common.ts'; -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function createEmpty(): AstTypes.ArrayExpression { const arrayExpression: AstTypes.ArrayExpression = { diff --git a/packages/core/tooling/js/common.ts b/packages/core/tooling/js/common.ts index c50900f16..e7035b40f 100644 --- a/packages/core/tooling/js/common.ts +++ b/packages/core/tooling/js/common.ts @@ -1,10 +1,4 @@ -import { - type AstTypes, - Walker, - parseScript, - serializeScript, - stripAst -} from '@sveltejs/ast-tooling'; +import { type AstTypes, Walker, parseScript, serializeScript, stripAst } from '../index.ts'; import decircular from 'decircular'; import dedent from 'dedent'; diff --git a/packages/core/tooling/js/exports.ts b/packages/core/tooling/js/exports.ts index d09f198d6..6ccf02320 100644 --- a/packages/core/tooling/js/exports.ts +++ b/packages/core/tooling/js/exports.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export type ExportDefaultReturn = { astNode: AstTypes.ExportDefaultDeclaration; diff --git a/packages/core/tooling/js/function.ts b/packages/core/tooling/js/function.ts index 672394e51..f67019822 100644 --- a/packages/core/tooling/js/function.ts +++ b/packages/core/tooling/js/function.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function call(name: string, args: string[]): AstTypes.CallExpression { const callExpression: AstTypes.CallExpression = { diff --git a/packages/core/tooling/js/imports.ts b/packages/core/tooling/js/imports.ts index 617466761..877d747c3 100644 --- a/packages/core/tooling/js/imports.ts +++ b/packages/core/tooling/js/imports.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { areNodesEqual } from './common.ts'; export function addEmpty(ast: AstTypes.Program, importFrom: string): void { diff --git a/packages/core/tooling/js/index.ts b/packages/core/tooling/js/index.ts index 7e556569d..08482f145 100644 --- a/packages/core/tooling/js/index.ts +++ b/packages/core/tooling/js/index.ts @@ -6,4 +6,4 @@ export * as imports from './imports.ts'; export * as variables from './variables.ts'; export * as exports from './exports.ts'; export * as kit from './kit.ts'; -export type { AstTypes } from '@sveltejs/ast-tooling'; +export type { AstTypes } from '../index.ts'; diff --git a/packages/core/tooling/js/kit.ts b/packages/core/tooling/js/kit.ts index 9f4f25c9d..d9a38a4a6 100644 --- a/packages/core/tooling/js/kit.ts +++ b/packages/core/tooling/js/kit.ts @@ -1,4 +1,4 @@ -import { Walker, type AstTypes } from '@sveltejs/ast-tooling'; +import { Walker, type AstTypes } from '../index.ts'; import { common, functions, imports, variables, exports } from '../js/index.ts'; export function addGlobalAppInterface( diff --git a/packages/core/tooling/js/object.ts b/packages/core/tooling/js/object.ts index 22ffb19ca..a909aa72e 100644 --- a/packages/core/tooling/js/object.ts +++ b/packages/core/tooling/js/object.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function property( ast: AstTypes.ObjectExpression, diff --git a/packages/ast-tooling/ts-estree.ts b/packages/core/tooling/js/ts-estree.ts similarity index 100% rename from packages/ast-tooling/ts-estree.ts rename to packages/core/tooling/js/ts-estree.ts diff --git a/packages/core/tooling/js/variables.ts b/packages/core/tooling/js/variables.ts index 1390343cf..bd652dfd1 100644 --- a/packages/core/tooling/js/variables.ts +++ b/packages/core/tooling/js/variables.ts @@ -1,4 +1,4 @@ -import type { AstTypes } from '@sveltejs/ast-tooling'; +import type { AstTypes } from '../index.ts'; export function declaration( ast: AstTypes.Program | AstTypes.Declaration, diff --git a/packages/core/tooling/parsers.ts b/packages/core/tooling/parsers.ts index 846cb8ea4..f7764d34f 100644 --- a/packages/core/tooling/parsers.ts +++ b/packages/core/tooling/parsers.ts @@ -1,4 +1,4 @@ -import * as tools from '@sveltejs/ast-tooling'; +import * as utils from './index.ts'; import MagicString from 'magic-string'; type ParseBase = { @@ -6,31 +6,31 @@ type ParseBase = { generateCode(): string; }; -export function parseScript(source: string): { ast: tools.AstTypes.Program } & ParseBase { - const ast = tools.parseScript(source); - const generateCode = () => tools.serializeScript(ast, source); +export function parseScript(source: string): { ast: utils.AstTypes.Program } & ParseBase { + const ast = utils.parseScript(source); + const generateCode = () => utils.serializeScript(ast, source); return { ast, source, generateCode }; } -export function parseCss(source: string): { ast: tools.CssAst } & ParseBase { - const ast = tools.parseCss(source); +export function parseCss(source: string): { ast: utils.CssAst } & ParseBase { + const ast = utils.parseCss(source); const generateCode = () => ast.toString(); return { ast, source, generateCode }; } -export function parseHtml(source: string): { ast: tools.HtmlDocument } & ParseBase { - const ast = tools.parseHtml(source); - const generateCode = () => tools.serializeHtml(ast); +export function parseHtml(source: string): { ast: utils.HtmlDocument } & ParseBase { + const ast = utils.parseHtml(source); + const generateCode = () => utils.serializeHtml(ast); return { ast, source, generateCode }; } export function parseJson(source: string): { data: any } & ParseBase { if (!source) source = '{}'; - const data = tools.parseJson(source); - const generateCode = () => tools.serializeJson(source, data); + const data = utils.parseJson(source); + const generateCode = () => utils.serializeJson(source, data); return { data, source, generateCode }; } diff --git a/packages/core/vitest.config.ts b/packages/core/vitest.config.ts index 8b52c7a67..6aa2d6afb 100644 --- a/packages/core/vitest.config.ts +++ b/packages/core/vitest.config.ts @@ -3,6 +3,6 @@ import { defineProject } from 'vitest/config'; export default defineProject({ test: { name: 'core', - include: ['./tests/**/index.ts'] + include: ['./tests/**/index.ts', './tests/*.ts'] } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11a9ea785..bd18dcc7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,45 +88,6 @@ importers: specifier: workspace:* version: link:../core - packages/ast-tooling: - devDependencies: - '@sveltejs/acorn-typescript': - specifier: ^1.0.1 - version: 1.0.5(acorn@8.14.0) - '@types/estree': - specifier: ^1.0.6 - version: 1.0.6 - acorn: - specifier: ^8.14.0 - version: 8.14.0 - dedent: - specifier: ^1.5.3 - version: 1.5.3 - dom-serializer: - specifier: ^2.0.0 - version: 2.0.0 - domhandler: - specifier: ^5.0.3 - version: 5.0.3 - domutils: - specifier: ^3.1.0 - version: 3.1.0 - esrap: - specifier: ^1.4.5 - version: 1.4.5 - htmlparser2: - specifier: ^9.1.0 - version: 9.1.0 - postcss: - specifier: ^8.4.49 - version: 8.5.1 - silver-fleece: - specifier: ^1.2.1 - version: 1.2.1 - zimmerframe: - specifier: ^1.1.2 - version: 1.1.2 - packages/clack-core: devDependencies: picocolors: @@ -206,26 +167,55 @@ importers: version: 0.41.0(typescript@5.7.2) packages/core: - dependencies: - '@sveltejs/ast-tooling': - specifier: workspace:* - version: link:../ast-tooling devDependencies: + '@sveltejs/acorn-typescript': + specifier: ^1.0.1 + version: 1.0.5(acorn@8.14.0) '@sveltejs/clack-prompts': specifier: workspace:* version: link:../clack-prompts + '@types/estree': + specifier: ^1.0.6 + version: 1.0.6 + acorn: + specifier: ^8.14.0 + version: 8.14.0 decircular: specifier: ^1.0.0 version: 1.0.0 dedent: specifier: ^1.5.3 version: 1.5.3 + dom-serializer: + specifier: ^2.0.0 + version: 2.0.0 + domhandler: + specifier: ^5.0.3 + version: 5.0.3 + domutils: + specifier: ^3.1.0 + version: 3.1.0 + esrap: + specifier: ^1.4.5 + version: 1.4.5 + htmlparser2: + specifier: ^9.1.0 + version: 9.1.0 magic-string: specifier: ^0.30.15 version: 0.30.17 picocolors: specifier: ^1.1.1 version: 1.1.1 + postcss: + specifier: ^8.4.49 + version: 8.5.3 + silver-fleece: + specifier: ^1.2.1 + version: 1.2.1 + zimmerframe: + specifier: ^1.1.2 + version: 1.1.2 packages/create: devDependencies: diff --git a/rolldown.config.js b/rolldown.config.js index 5d193af76..3ffbb1da2 100644 --- a/rolldown.config.js +++ b/rolldown.config.js @@ -121,7 +121,6 @@ function getConfig(project) { export default [ getConfig('clack-core'), getConfig('clack-prompts'), - getConfig('ast-tooling'), getConfig('create'), getConfig('core'), getConfig('cli')