sv
Version:
A CLI for creating and updating SvelteKit projects
1,148 lines (1,139 loc) • 39.1 kB
JavaScript
import { __commonJS, __toESM, be, detect, getUserAgent, log, parseJson, parseScript as parseScript$1, parseScript$1 as parseScript, resolveCommand, serializeScript, stripAst, up, walk_exports } from "./package-manager-Hi1R0gbv.js";
import fs from "node:fs";
import path from "node:path";
import process$1 from "node:process";
//#region node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js
var require_picocolors = __commonJS({ "node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js"(exports, module) {
let p = process || {}, argv = p.argv || [], env$1 = p.env || {};
let isColorSupported = !(!!env$1.NO_COLOR || argv.includes("--no-color")) && (!!env$1.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env$1.TERM !== "dumb" || !!env$1.CI);
let formatter = (open, close, replace = open) => (input) => {
let string = "" + input, index = string.indexOf(close, open.length);
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
};
let replaceClose = (string, close, replace, index) => {
let result = "", cursor = 0;
do {
result += string.substring(cursor, index) + replace;
cursor = index + close.length;
index = string.indexOf(close, cursor);
} while (~index);
return result + string.substring(cursor);
};
let createColors = (enabled = isColorSupported) => {
let f = enabled ? formatter : () => String;
return {
isColorSupported: enabled,
reset: f("\x1B[0m", "\x1B[0m"),
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
italic: f("\x1B[3m", "\x1B[23m"),
underline: f("\x1B[4m", "\x1B[24m"),
inverse: f("\x1B[7m", "\x1B[27m"),
hidden: f("\x1B[8m", "\x1B[28m"),
strikethrough: f("\x1B[9m", "\x1B[29m"),
black: f("\x1B[30m", "\x1B[39m"),
red: f("\x1B[31m", "\x1B[39m"),
green: f("\x1B[32m", "\x1B[39m"),
yellow: f("\x1B[33m", "\x1B[39m"),
blue: f("\x1B[34m", "\x1B[39m"),
magenta: f("\x1B[35m", "\x1B[39m"),
cyan: f("\x1B[36m", "\x1B[39m"),
white: f("\x1B[37m", "\x1B[39m"),
gray: f("\x1B[90m", "\x1B[39m"),
bgBlack: f("\x1B[40m", "\x1B[49m"),
bgRed: f("\x1B[41m", "\x1B[49m"),
bgGreen: f("\x1B[42m", "\x1B[49m"),
bgYellow: f("\x1B[43m", "\x1B[49m"),
bgBlue: f("\x1B[44m", "\x1B[49m"),
bgMagenta: f("\x1B[45m", "\x1B[49m"),
bgCyan: f("\x1B[46m", "\x1B[49m"),
bgWhite: f("\x1B[47m", "\x1B[49m"),
blackBright: f("\x1B[90m", "\x1B[39m"),
redBright: f("\x1B[91m", "\x1B[39m"),
greenBright: f("\x1B[92m", "\x1B[39m"),
yellowBright: f("\x1B[93m", "\x1B[39m"),
blueBright: f("\x1B[94m", "\x1B[39m"),
magentaBright: f("\x1B[95m", "\x1B[39m"),
cyanBright: f("\x1B[96m", "\x1B[39m"),
whiteBright: f("\x1B[97m", "\x1B[39m"),
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
bgRedBright: f("\x1B[101m", "\x1B[49m"),
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
};
};
module.exports = createColors();
module.exports.createColors = createColors;
} });
//#endregion
//#region packages/cli/utils/env.ts
const TESTING = process$1.env.NODE_ENV?.toLowerCase() === "test";
//#endregion
//#region packages/core/dist/dedent-tgO2J0Ou.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS$1 = (cb, mod) => function() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all) __defProp(target, name, {
get: all[name],
enumerable: true
});
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
enumerableOnly && (symbols = symbols.filter(function(sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
})), keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread(target) {
for (var i = 1; i < arguments.length; i++) {
var source = null != arguments[i] ? arguments[i] : {};
i % 2 ? ownKeys(Object(source), !0).forEach(function(key) {
_defineProperty(target, key, source[key]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function(key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
return target;
}
function _defineProperty(obj, key, value) {
key = _toPropertyKey(key);
if (key in obj) Object.defineProperty(obj, key, {
value,
enumerable: true,
configurable: true,
writable: true
});
else obj[key] = value;
return obj;
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, "string");
return typeof key === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
if (typeof input !== "object" || input === null) return input;
var prim = input[Symbol.toPrimitive];
if (prim !== undefined) {
var res = prim.call(input, hint || "default");
if (typeof res !== "object") return res;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return (hint === "string" ? String : Number)(input);
}
const dedent = createDedent({});
var dedent_default = dedent;
function createDedent(options) {
dedent$1.withOptions = (newOptions) => createDedent(_objectSpread(_objectSpread({}, options), newOptions));
return dedent$1;
function dedent$1(strings, ...values) {
const raw = typeof strings === "string" ? [strings] : strings.raw;
const { escapeSpecialCharacters = Array.isArray(strings) } = options;
let result = "";
for (let i = 0; i < raw.length; i++) {
let next = raw[i];
if (escapeSpecialCharacters) next = next.replace(/\\\n[ \t]*/g, "").replace(/\\`/g, "`").replace(/\\\$/g, "$").replace(/\\\{/g, "{");
result += next;
if (i < values.length) result += values[i];
}
const lines = result.split("\n");
let mindent = null;
for (const l of lines) {
const m = l.match(/^(\s+)\S+/);
if (m) {
const indent = m[1].length;
if (!mindent) mindent = indent;
else mindent = Math.min(mindent, indent);
}
}
if (mindent !== null) {
const m = mindent;
result = lines.map((l) => l[0] === " " || l[0] === " " ? l.slice(m) : l).join("\n");
}
result = result.trim();
if (escapeSpecialCharacters) result = result.replace(/\\n/g, "\n");
return result;
}
}
//#endregion
//#region packages/core/dist/common-Dee02diz.js
function decircular(object) {
const seenObjects = new WeakMap();
function internalDecircular(value, path$1 = []) {
if (!(value !== null && typeof value === "object")) return value;
const existingPath = seenObjects.get(value);
if (existingPath) return `[Circular *${existingPath.join(".")}]`;
seenObjects.set(value, path$1);
const newValue = Array.isArray(value) ? [] : {};
for (const [key2, value2] of Object.entries(value)) newValue[key2] = internalDecircular(value2, [...path$1, key2]);
seenObjects.delete(value);
return newValue;
}
return internalDecircular(object);
}
var common_exports = {};
__export(common_exports, {
addFromString: () => addFromString,
addJsDocComment: () => addJsDocComment,
addJsDocTypeComment: () => addJsDocTypeComment,
addStatement: () => addStatement,
areNodesEqual: () => areNodesEqual,
blockStatement: () => blockStatement,
createLiteral: () => createLiteral,
createSpreadElement: () => createSpreadElement,
expressionFromString: () => expressionFromString,
expressionStatement: () => expressionStatement,
fromString: () => fromString,
hasNode: () => hasNode,
hasTypeProp: () => hasTypeProp,
satisfiesExpression: () => satisfiesExpression,
statementFromString: () => statementFromString,
typeAnnotateExpression: () => typeAnnotateExpression
});
function addJsDocTypeComment(node, type) {
const comment = {
type: "Block",
value: `* @type {${type}} `
};
addComment(node, comment);
}
function addJsDocComment(node, params) {
const commentLines = [];
for (const [key, value] of Object.entries(params)) commentLines.push(`@param {${key}} ${value}`);
const comment = {
type: "Block",
value: `*\n * ${commentLines.join("\n * ")}\n `
};
addComment(node, comment);
}
function addComment(node, comment) {
node.leadingComments ??= [];
const found = node.leadingComments.find((n) => n.type === "Block" && n.value === comment.value);
if (!found) node.leadingComments.push(comment);
}
function typeAnnotateExpression(node, type) {
const expression = {
type: "TSAsExpression",
expression: node,
typeAnnotation: {
type: "TSTypeReference",
typeName: {
type: "Identifier",
name: type
}
}
};
return expression;
}
function satisfiesExpression(node, type) {
const expression = {
type: "TSSatisfiesExpression",
expression: node,
typeAnnotation: {
type: "TSTypeReference",
typeName: {
type: "Identifier",
name: type
}
}
};
return expression;
}
function createSpreadElement(expression) {
return {
type: "SpreadElement",
argument: expression
};
}
function createLiteral(value = null) {
const literal = {
type: "Literal",
value
};
return literal;
}
function areNodesEqual(ast1, ast2) {
const ast1Clone = stripAst(decircular(ast1), ["loc", "raw"]);
const ast2Clone = stripAst(decircular(ast2), ["loc", "raw"]);
return serializeScript(ast1Clone) === serializeScript(ast2Clone);
}
function blockStatement() {
const statement = {
type: "BlockStatement",
body: []
};
return statement;
}
function expressionStatement(expression) {
const statement = {
type: "ExpressionStatement",
expression
};
return statement;
}
function addFromString(ast, value) {
const program = parseScript(dedent_default(value));
for (const childNode of program.body) ast.body.push(childNode);
}
function expressionFromString(value) {
const program = parseScript(dedent_default(value));
const statement = program.body[0];
if (statement.type !== "ExpressionStatement") throw new Error("value passed was not an expression");
return statement.expression;
}
function statementFromString(value) {
return fromString(value);
}
function fromString(value) {
const program = parseScript(dedent_default(value));
const statement = program.body[0];
return statement;
}
function addStatement(ast, statement) {
if (!hasNode(ast, statement)) ast.body.push(statement);
}
function hasNode(ast, nodeToMatch) {
let found = false;
walk_exports.walk(ast, null, { _(node, { next, stop }) {
if (node.type === nodeToMatch.type) {
found = areNodesEqual(node, nodeToMatch);
if (found) stop();
}
next();
} });
return found;
}
function hasTypeProp(name, node) {
return node.type === "TSPropertySignature" && node.key.type === "Identifier" && node.key.name === name;
}
//#endregion
//#region packages/core/dist/js.js
var array_exports = {};
__export(array_exports, {
createEmpty: () => createEmpty$1,
push: () => push,
unshift: () => unshift
});
function createEmpty$1() {
const arrayExpression = {
type: "ArrayExpression",
elements: []
};
return arrayExpression;
}
function push(ast, data) {
insertElement(ast, data, true);
}
function unshift(ast, data) {
insertElement(ast, data, false);
}
function insertElement(ast, data, insertEnd) {
if (typeof data === "string") {
const existingLiterals = ast.elements.filter((x) => x !== null && x.type === "Literal");
let literal = existingLiterals.find((x) => x.value === data);
if (!literal) {
literal = {
type: "Literal",
value: data
};
if (insertEnd) ast.elements.push(literal);
else ast.elements.unshift(literal);
}
} else {
const elements = ast.elements;
const anyNodeEquals = elements.some((node) => node && areNodesEqual(data, node));
if (!anyNodeEquals) if (insertEnd) ast.elements.push(data);
else ast.elements.unshift(data);
}
}
var object_exports = {};
__export(object_exports, {
create: () => create,
createEmpty: () => createEmpty,
overrideProperties: () => overrideProperties,
overrideProperty: () => overrideProperty,
properties: () => properties,
property: () => property,
removeProperty: () => removeProperty
});
function property(ast, name, fallback) {
const objectExpression = ast;
const properties$1 = objectExpression.properties.filter((x) => x.type === "Property");
let property$1 = properties$1.find((x) => x.key.name === name);
let propertyValue;
if (property$1) propertyValue = property$1.value;
else {
let isShorthand = false;
if (fallback.type === "Identifier") {
const identifier$1 = fallback;
isShorthand = identifier$1.name === name;
}
propertyValue = fallback;
property$1 = {
type: "Property",
shorthand: isShorthand,
key: {
type: "Identifier",
name
},
value: propertyValue,
kind: "init",
computed: false,
method: false
};
objectExpression.properties.push(property$1);
}
return propertyValue;
}
function overrideProperty(ast, name, value) {
const objectExpression = ast;
const properties$1 = objectExpression.properties.filter((x) => x.type === "Property");
const prop = properties$1.find((x) => x.key.name === name);
if (!prop) return property(ast, name, value);
prop.value = value;
return value;
}
function overrideProperties(ast, obj) {
for (const [prop, value] of Object.entries(obj)) {
if (value === undefined) continue;
overrideProperty(ast, prop, value);
}
}
function properties(ast, obj) {
for (const [prop, value] of Object.entries(obj)) {
if (value === undefined) continue;
property(ast, prop, value);
}
}
function removeProperty(ast, property$1) {
const properties$1 = ast.properties.filter((x) => x.type === "Property");
const propIdx = properties$1.findIndex((x) => x.key.name === property$1);
if (propIdx !== -1) ast.properties.splice(propIdx, 1);
}
function create(obj) {
const objExpression = createEmpty();
for (const [prop, value] of Object.entries(obj)) {
if (value === undefined) continue;
property(objExpression, prop, value);
}
return objExpression;
}
function createEmpty() {
const objectExpression = {
type: "ObjectExpression",
properties: []
};
return objectExpression;
}
var function_exports = {};
__export(function_exports, {
argumentByIndex: () => argumentByIndex,
arrowFunction: () => arrowFunction,
call: () => call,
callByIdentifier: () => callByIdentifier
});
function call(name, args) {
const callExpression = {
type: "CallExpression",
callee: {
type: "Identifier",
name
},
arguments: [],
optional: false
};
for (const argument of args) callExpression.arguments.push({
type: "Literal",
value: argument
});
return callExpression;
}
function callByIdentifier(name, args) {
const callExpression = {
type: "CallExpression",
callee: {
type: "Identifier",
name
},
arguments: [],
optional: false
};
for (const argument of args) {
const identifier$1 = {
type: "Identifier",
name: argument
};
callExpression.arguments.push(identifier$1);
}
return callExpression;
}
function arrowFunction(async, body) {
const arrowFunction$1 = {
type: "ArrowFunctionExpression",
async,
body,
params: [],
expression: body.type !== "BlockStatement"
};
return arrowFunction$1;
}
function argumentByIndex(ast, i, fallback) {
if (i < ast.arguments.length) return ast.arguments[i];
ast.arguments.push(fallback);
return fallback;
}
var imports_exports = {};
__export(imports_exports, {
addDefault: () => addDefault,
addEmpty: () => addEmpty,
addNamed: () => addNamed,
addNamespace: () => addNamespace
});
function addEmpty(ast, importFrom) {
const expectedImportDeclaration = {
type: "ImportDeclaration",
source: {
type: "Literal",
value: importFrom
},
specifiers: [],
importKind: "value"
};
addImportIfNecessary(ast, expectedImportDeclaration);
}
function addNamespace(ast, importFrom, importAs) {
const expectedImportDeclaration = {
type: "ImportDeclaration",
importKind: "value",
source: {
type: "Literal",
value: importFrom
},
specifiers: [{
type: "ImportNamespaceSpecifier",
local: {
type: "Identifier",
name: importAs
}
}]
};
addImportIfNecessary(ast, expectedImportDeclaration);
}
function addDefault(ast, importFrom, importAs) {
const expectedImportDeclaration = {
type: "ImportDeclaration",
source: {
type: "Literal",
value: importFrom
},
specifiers: [{
type: "ImportDefaultSpecifier",
local: {
type: "Identifier",
name: importAs
}
}],
importKind: "value"
};
addImportIfNecessary(ast, expectedImportDeclaration);
}
function addNamed(ast, importFrom, exportedAsImportAs, isType = false) {
const specifiers = Object.entries(exportedAsImportAs).map(([key, value]) => {
const specifier = {
type: "ImportSpecifier",
imported: {
type: "Identifier",
name: key
},
local: {
type: "Identifier",
name: value
}
};
return specifier;
});
let importDecl;
walk_exports.walk(ast, null, { ImportDeclaration(node) {
if (node.source.value === importFrom && node.specifiers) importDecl = node;
} });
if (importDecl) {
specifiers.forEach((specifierToAdd) => {
const sourceExists = importDecl?.specifiers?.every((existingSpecifier) => existingSpecifier.type === "ImportSpecifier" && existingSpecifier.local?.name !== specifierToAdd.local?.name && existingSpecifier.imported.type === "Identifier" && specifierToAdd.imported.type === "Identifier" && existingSpecifier.imported.name !== specifierToAdd.imported.name);
if (sourceExists) importDecl?.specifiers?.push(specifierToAdd);
});
return;
}
const expectedImportDeclaration = {
type: "ImportDeclaration",
source: {
type: "Literal",
value: importFrom
},
specifiers,
importKind: isType ? "type" : "value"
};
ast.body.unshift(expectedImportDeclaration);
}
function addImportIfNecessary(ast, expectedImportDeclaration) {
const importDeclarations = ast.body.filter((x) => x.type === "ImportDeclaration");
const importDeclaration = importDeclarations.find((x) => areNodesEqual(x, expectedImportDeclaration));
if (!importDeclaration) ast.body.unshift(expectedImportDeclaration);
}
var variables_exports = {};
__export(variables_exports, {
declaration: () => declaration,
identifier: () => identifier,
typeAnnotateDeclarator: () => typeAnnotateDeclarator
});
function declaration(ast, kind, name, value) {
const declarations = ast.type === "Program" ? ast.body.filter((x) => x.type === "VariableDeclaration") : [ast];
let declaration$1 = declarations.find((x) => {
const declarator = x.declarations[0];
const identifier$1 = declarator.id;
return identifier$1.name === name;
});
if (declaration$1) return declaration$1;
declaration$1 = {
type: "VariableDeclaration",
kind,
declarations: [{
type: "VariableDeclarator",
id: {
type: "Identifier",
name
},
init: value
}]
};
return declaration$1;
}
function identifier(name) {
const identifier$1 = {
type: "Identifier",
name
};
return identifier$1;
}
function typeAnnotateDeclarator(node, typeName) {
if (node.id.type === "Identifier") node.id.typeAnnotation = {
type: "TSTypeAnnotation",
typeAnnotation: {
type: "TSTypeReference",
typeName: {
type: "Identifier",
name: typeName
}
}
};
return node;
}
var exports_exports = {};
__export(exports_exports, {
defaultExport: () => defaultExport,
namedExport: () => namedExport
});
function defaultExport(ast, fallbackDeclaration) {
const existingNode = ast.body.find((x) => x.type === "ExportDefaultDeclaration");
if (!existingNode) {
const node = {
type: "ExportDefaultDeclaration",
declaration: fallbackDeclaration
};
ast.body.push(node);
return {
astNode: node,
value: fallbackDeclaration
};
}
const exportDefaultDeclaration = existingNode;
if (exportDefaultDeclaration.declaration.type === "Identifier") {
const identifier$1 = exportDefaultDeclaration.declaration;
let variableDeclaration;
let variableDeclarator;
for (const declaration$2 of ast.body) {
if (declaration$2.type !== "VariableDeclaration") continue;
const declarator = declaration$2.declarations.find((d) => d.type === "VariableDeclarator" && d.id.type === "Identifier" && d.id.name === identifier$1.name);
variableDeclarator = declarator;
variableDeclaration = declaration$2;
}
if (!variableDeclaration || !variableDeclarator) throw new Error(`Unable to find exported variable '${identifier$1.name}'`);
const value = variableDeclarator.init;
return {
astNode: exportDefaultDeclaration,
value
};
}
const declaration$1 = exportDefaultDeclaration.declaration;
return {
astNode: exportDefaultDeclaration,
value: declaration$1
};
}
function namedExport(ast, name, fallback) {
const namedExports = ast.body.filter((x) => x.type === "ExportNamedDeclaration");
let namedExport$1 = namedExports.find((x) => {
const variableDeclaration = x.declaration;
const variableDeclarator = variableDeclaration.declarations[0];
const identifier$1 = variableDeclarator.id;
return identifier$1.name === name;
});
if (namedExport$1) return namedExport$1;
namedExport$1 = {
type: "ExportNamedDeclaration",
declaration: fallback,
specifiers: []
};
ast.body.push(namedExport$1);
return namedExport$1;
}
var kit_exports = {};
__export(kit_exports, {
addGlobalAppInterface: () => addGlobalAppInterface,
addHooksHandle: () => addHooksHandle
});
function addGlobalAppInterface(ast, name) {
let globalDecl = ast.body.filter((n) => n.type === "TSModuleDeclaration").find((m) => m.global && m.declare);
if (!globalDecl) {
globalDecl = fromString("declare global {}");
ast.body.push(globalDecl);
}
if (globalDecl.body?.type !== "TSModuleBlock") throw new Error("Unexpected body type of `declare global` in `src/app.d.ts`");
let app;
let interfaceNode;
walk_exports.walk(globalDecl, null, {
TSModuleDeclaration(node, { next }) {
if (node.id.type === "Identifier" && node.id.name === "App") app = node;
next();
},
TSInterfaceDeclaration(node) {
if (node.id.type === "Identifier" && node.id.name === name) interfaceNode = node;
}
});
if (!app) {
app = fromString("namespace App {}");
globalDecl.body.body.push(app);
}
if (app.body?.type !== "TSModuleBlock") throw new Error("Unexpected body type of `namespace App` in `src/app.d.ts`");
if (!interfaceNode) {
interfaceNode = fromString(`interface ${name} {}`);
app.body.body.push(interfaceNode);
}
return interfaceNode;
}
function addHooksHandle(ast, typescript, newHandleName, handleContent) {
if (typescript) addNamed(ast, "@sveltejs/kit", { Handle: "Handle" }, true);
let isSpecifier = false;
let handleName = "handle";
let exportDecl;
let originalHandleDecl;
walk_exports.walk(ast, null, { ExportNamedDeclaration(node) {
let maybeHandleDecl;
const handleSpecifier = node.specifiers?.find((s) => s.exported.type === "Identifier" && s.exported.name === "handle");
if (handleSpecifier && handleSpecifier.local.type === "Identifier" && handleSpecifier.exported.type === "Identifier") {
isSpecifier = true;
handleName = handleSpecifier.local?.name ?? handleSpecifier.exported.name;
const handleFunc = ast.body.find((n) => isFunctionDeclaration(n, handleName));
const handleVar = ast.body.find((n) => isVariableDeclaration(n, handleName));
maybeHandleDecl = handleFunc ?? handleVar;
}
maybeHandleDecl ??= node.declaration ?? undefined;
if (maybeHandleDecl && isVariableDeclaration(maybeHandleDecl, handleName)) {
exportDecl = node;
originalHandleDecl = maybeHandleDecl;
}
if (maybeHandleDecl && isFunctionDeclaration(maybeHandleDecl, handleName)) {
exportDecl = node;
originalHandleDecl = maybeHandleDecl;
}
} });
const newHandle = expressionFromString(handleContent);
if (hasNode(ast, newHandle)) return;
if (!originalHandleDecl || !exportDecl) {
const newDecl$1 = declaration(ast, "const", newHandleName, newHandle);
if (typescript) {
const declarator = newDecl$1.declarations[0];
typeAnnotateDeclarator(declarator, "Handle");
}
ast.body.push(newDecl$1);
const handleDecl = declaration(ast, "const", handleName, expressionFromString(newHandleName));
if (typescript) {
const declarator = handleDecl.declarations[0];
typeAnnotateDeclarator(declarator, "Handle");
}
namedExport(ast, handleName, handleDecl);
return;
}
const newDecl = declaration(ast, "const", newHandleName, newHandle);
if (typescript) {
const declarator = newDecl.declarations[0];
typeAnnotateDeclarator(declarator, "Handle");
}
let sequence;
if (originalHandleDecl.type === "VariableDeclaration") {
const handle = originalHandleDecl.declarations.find((d) => d.type === "VariableDeclarator" && usingSequence(d, handleName));
sequence = handle?.init;
}
if (sequence) {
const hasNewArg = sequence.arguments.some((arg) => arg.type === "Identifier" && arg.name === newHandleName);
if (!hasNewArg) sequence.arguments.push(identifier(newHandleName));
ast.body = ast.body.filter((n) => n !== originalHandleDecl && n !== exportDecl && n !== newDecl);
if (isSpecifier) ast.body.push(newDecl, originalHandleDecl, exportDecl);
else ast.body.push(newDecl, exportDecl);
}
const NEW_HANDLE_NAME = "originalHandle";
const sequenceCall = callByIdentifier("sequence", [NEW_HANDLE_NAME, newHandleName]);
const newHandleDecl = declaration(ast, "const", handleName, sequenceCall);
addNamed(ast, "@sveltejs/kit/hooks", { sequence: "sequence" });
let renameRequired = false;
if (originalHandleDecl && isVariableDeclaration(originalHandleDecl, handleName)) {
const handle = getVariableDeclarator(originalHandleDecl, handleName);
if (handle && handle.id.type === "Identifier" && handle.init?.type !== "Identifier") {
renameRequired = true;
handle.id.name = NEW_HANDLE_NAME;
}
}
if (originalHandleDecl && isFunctionDeclaration(originalHandleDecl, handleName)) {
renameRequired = true;
originalHandleDecl.id.name = NEW_HANDLE_NAME;
}
ast.body = ast.body.filter((n) => n !== originalHandleDecl && n !== exportDecl && n !== newDecl);
if (isSpecifier) ast.body.push(originalHandleDecl, newDecl, newHandleDecl, exportDecl);
if (exportDecl.declaration && renameRequired) {
ast.body.push(exportDecl.declaration, newDecl);
namedExport(ast, handleName, newHandleDecl);
} else if (exportDecl.declaration && isVariableDeclaration(originalHandleDecl, handleName)) {
const variableDeclarator = getVariableDeclarator(originalHandleDecl, handleName);
const sequenceCall$1 = callByIdentifier("sequence", [(variableDeclarator?.init).name, newHandleName]);
const newHandleDecl$1 = declaration(ast, "const", handleName, sequenceCall$1);
if (typescript) {
const declarator = newHandleDecl$1.declarations[0];
typeAnnotateDeclarator(declarator, "Handle");
}
ast.body.push(newDecl);
namedExport(ast, handleName, newHandleDecl$1);
}
}
function usingSequence(node, handleName) {
return node.id.type === "Identifier" && node.id.name === handleName && node.init?.type === "CallExpression" && node.init.callee.type === "Identifier" && node.init.callee.name === "sequence";
}
function isVariableDeclaration(node, variableName) {
return node.type === "VariableDeclaration" && getVariableDeclarator(node, variableName) !== undefined;
}
function getVariableDeclarator(node, handleName) {
return node.declarations.find((d) => d.type === "VariableDeclarator" && d.id.type === "Identifier" && d.id.name === handleName);
}
function isFunctionDeclaration(node, funcName) {
return node.type === "FunctionDeclaration" && node.id?.name === funcName;
}
//#endregion
//#region packages/cli/commands/add/utils.ts
var import_picocolors$1 = __toESM(require_picocolors(), 1);
function getPackageJson(cwd) {
const packageText = readFile(cwd, commonFilePaths.packageJson);
if (!packageText) {
const pkgPath = path.join(cwd, commonFilePaths.packageJson);
throw new Error(`Invalid workspace: missing '${pkgPath}'`);
}
const { data, generateCode } = parseJson(packageText);
return {
source: packageText,
data,
generateCode
};
}
async function formatFiles(options) {
const args = [
"prettier",
"--write",
"--ignore-unknown",
...options.paths
];
const cmd = resolveCommand(options.packageManager, "execute-local", args);
await be(cmd.command, cmd.args, {
nodeOptions: {
cwd: options.cwd,
stdio: "pipe"
},
throwOnError: true
});
}
function readFile(cwd, filePath) {
const fullFilePath = path.resolve(cwd, filePath);
if (!fileExists(cwd, filePath)) return "";
const text = fs.readFileSync(fullFilePath, "utf8");
return text;
}
function installPackages(dependencies, workspace) {
const { data, generateCode } = getPackageJson(workspace.cwd);
for (const dependency of dependencies) if (dependency.dev) {
data.devDependencies ??= {};
data.devDependencies[dependency.pkg] = dependency.version;
} else {
data.dependencies ??= {};
data.dependencies[dependency.pkg] = dependency.version;
}
if (data.dependencies) data.dependencies = alphabetizeProperties(data.dependencies);
if (data.devDependencies) data.devDependencies = alphabetizeProperties(data.devDependencies);
writeFile(workspace, commonFilePaths.packageJson, generateCode());
return commonFilePaths.packageJson;
}
function alphabetizeProperties(obj) {
const orderedObj = {};
const sortedEntries = Object.entries(obj).sort(([a], [b]) => a.localeCompare(b));
for (const [key, value] of sortedEntries) orderedObj[key] = value;
return orderedObj;
}
function writeFile(workspace, filePath, content) {
const fullFilePath = path.resolve(workspace.cwd, filePath);
const fullDirectoryPath = path.dirname(fullFilePath);
if (content && !content.endsWith("\n")) content += "\n";
if (!fs.existsSync(fullDirectoryPath)) fs.mkdirSync(fullDirectoryPath, { recursive: true });
fs.writeFileSync(fullFilePath, content, "utf8");
}
function fileExists(cwd, filePath) {
const fullFilePath = path.resolve(cwd, filePath);
return fs.existsSync(fullFilePath);
}
const commonFilePaths = {
packageJson: "package.json",
svelteConfig: "svelte.config.js",
tsconfig: "tsconfig.json",
viteConfigTS: "vite.config.ts"
};
function getHighlighter() {
return {
command: (str) => import_picocolors$1.default.bold(import_picocolors$1.default.cyanBright(str)),
env: (str) => import_picocolors$1.default.yellow(str),
path: (str) => import_picocolors$1.default.green(str),
route: (str) => import_picocolors$1.default.bold(str),
website: (str) => import_picocolors$1.default.whiteBright(str)
};
}
//#endregion
//#region packages/cli/commands/add/workspace.ts
async function createWorkspace({ cwd, options = {}, packageManager }) {
const resolvedCwd = path.resolve(cwd);
const viteConfigPath = path.join(resolvedCwd, commonFilePaths.viteConfigTS);
let usesTypescript = fs.existsSync(viteConfigPath);
if (TESTING) usesTypescript ||= fs.existsSync(path.join(resolvedCwd, commonFilePaths.tsconfig));
else usesTypescript ||= up(commonFilePaths.tsconfig, { cwd }) !== undefined;
let dependencies = {};
let directory = resolvedCwd;
const root = findRoot(resolvedCwd);
while (directory && directory !== root) {
if (fs.existsSync(path.join(directory, commonFilePaths.packageJson))) {
const { data: packageJson } = getPackageJson(directory);
dependencies = {
...packageJson.devDependencies,
...packageJson.dependencies,
...dependencies
};
}
directory = path.dirname(directory);
}
for (const [key, value] of Object.entries(dependencies)) dependencies[key] = value.replaceAll(/[^\d|.]/g, "");
return {
cwd: resolvedCwd,
options,
packageManager: packageManager ?? (await detect({ cwd }))?.name ?? getUserAgent() ?? "npm",
typescript: usesTypescript,
kit: dependencies["@sveltejs/kit"] ? parseKitOptions(resolvedCwd) : undefined,
dependencyVersion: (pkg) => dependencies[pkg]
};
}
function findRoot(cwd) {
const { root } = path.parse(cwd);
let directory = cwd;
while (directory && directory !== root) {
if (fs.existsSync(path.join(directory, commonFilePaths.packageJson))) {
if (fs.existsSync(path.join(directory, "pnpm-workspace.yaml"))) return directory;
const { data } = getPackageJson(directory);
if (data.workspaces) return directory;
}
directory = path.dirname(directory);
}
return root;
}
function parseKitOptions(cwd) {
const configSource = readFile(cwd, commonFilePaths.svelteConfig);
const { ast } = parseScript$1(configSource);
const defaultExport$1 = ast.body.find((s) => s.type === "ExportDefaultDeclaration");
if (!defaultExport$1) throw Error("Missing default export in `svelte.config.js`");
let objectExpression;
if (defaultExport$1.declaration.type === "Identifier") {
const identifier$1 = defaultExport$1.declaration;
for (const declaration$1 of ast.body) {
if (declaration$1.type !== "VariableDeclaration") continue;
const declarator = declaration$1.declarations.find((d) => d.type === "VariableDeclarator" && d.id.type === "Identifier" && d.id.name === identifier$1.name);
if (declarator?.init?.type !== "ObjectExpression") continue;
objectExpression = declarator.init;
}
if (!objectExpression) throw Error("Unable to find svelte config object expression from `svelte.config.js`");
} else if (defaultExport$1.declaration.type === "ObjectExpression") objectExpression = defaultExport$1.declaration;
if (!objectExpression) throw new Error("Unexpected svelte config shape from `svelte.config.js`");
const kit = object_exports.property(objectExpression, "kit", object_exports.createEmpty());
const files = object_exports.property(kit, "files", object_exports.createEmpty());
const routes = object_exports.property(files, "routes", common_exports.createLiteral());
const lib = object_exports.property(files, "lib", common_exports.createLiteral());
const routesDirectory = routes.value || "src/routes";
const libDirectory = lib.value || "src/lib";
return {
routesDirectory,
libDirectory
};
}
//#endregion
//#region packages/cli/lib/install.ts
var import_picocolors = __toESM(require_picocolors(), 1);
async function installAddon({ addons, cwd, options, packageManager = "npm" }) {
const workspace = await createWorkspace({
cwd,
packageManager
});
const addonSetupResults = setupAddons(Object.values(addons), workspace);
return await applyAddons({
addons,
workspace,
options,
addonSetupResults
});
}
async function applyAddons({ addons, workspace, addonSetupResults, options }) {
const filesToFormat = new Set();
const allPnpmBuildDependencies = [];
const mapped = Object.entries(addons).map(([, addon]) => addon);
const ordered = orderAddons(mapped, addonSetupResults);
for (const addon of ordered) {
workspace = await createWorkspace({
...workspace,
options: options[addon.id]
});
const { files, pnpmBuildDependencies } = await runAddon({
workspace,
addon,
multiple: ordered.length > 1
});
files.forEach((f) => filesToFormat.add(f));
pnpmBuildDependencies.forEach((s) => allPnpmBuildDependencies.push(s));
}
return {
filesToFormat: Array.from(filesToFormat),
pnpmBuildDependencies: allPnpmBuildDependencies
};
}
function setupAddons(addons, workspace) {
const addonSetupResults = {};
for (const addon of addons) {
const setupResult = {
unsupported: [],
dependsOn: []
};
addon.setup?.({
...workspace,
dependsOn: (name) => setupResult.dependsOn.push(name),
unsupported: (reason) => setupResult.unsupported.push(reason)
});
addonSetupResults[addon.id] = setupResult;
}
return addonSetupResults;
}
async function runAddon({ addon, multiple, workspace }) {
const files = new Set();
for (const [id, question] of Object.entries(addon.options)) if (question.condition?.(workspace.options) !== false) workspace.options[id] ??= question.default;
const dependencies = [];
const pnpmBuildDependencies = [];
const sv = {
file: (path$1, content) => {
try {
const exists = fileExists(workspace.cwd, path$1);
let fileContent = exists ? readFile(workspace.cwd, path$1) : "";
fileContent = content(fileContent);
if (!fileContent) return fileContent;
writeFile(workspace, path$1, fileContent);
files.add(path$1);
} catch (e) {
if (e instanceof Error) throw new Error(`Unable to process '${path$1}'. Reason: ${e.message}`);
throw e;
}
},
execute: async (commandArgs, stdio) => {
const { command, args } = resolveCommand(workspace.packageManager, "execute", commandArgs);
const addonPrefix = multiple ? `${addon.id}: ` : "";
const executedCommand = `${command} ${args.join(" ")}`;
if (!TESTING) log.step(`${addonPrefix}Running external command ${import_picocolors.default.gray(`(${executedCommand})`)}`);
if (workspace.packageManager === "npm") args.unshift("--yes");
try {
await be(command, args, {
nodeOptions: {
cwd: workspace.cwd,
stdio: TESTING ? "pipe" : stdio
},
throwOnError: true
});
} catch (error) {
const typedError = error;
throw new Error(`Failed to execute scripts '${executedCommand}': ${typedError.message}`, { cause: typedError.output });
}
},
dependency: (pkg, version) => {
dependencies.push({
pkg,
version,
dev: false
});
},
devDependency: (pkg, version) => {
dependencies.push({
pkg,
version,
dev: true
});
},
pnpmBuildDependendency: (pkg) => {
pnpmBuildDependencies.push(pkg);
}
};
await addon.run({
...workspace,
sv
});
const pkgPath = installPackages(dependencies, workspace);
files.add(pkgPath);
return {
files: Array.from(files),
pnpmBuildDependencies
};
}
function orderAddons(addons, setupResults) {
return addons.sort((a, b) => setupResults[a.id]?.dependsOn?.length - setupResults[b.id]?.dependsOn?.length);
}
//#endregion
export { __commonJS$1, __export, __toESM$1, addFromString, applyAddons, array_exports, common_exports, createWorkspace, dedent_default, exports_exports, formatFiles, function_exports, getHighlighter, imports_exports, installAddon, kit_exports, object_exports, require_picocolors, setupAddons, variables_exports };