sv 0.6.2 → 0.6.3

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/bin.js CHANGED
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
  import require$$0 from 'node:events';
3
3
  import require$$1, { execSync } from 'node:child_process';
4
- import path$2, { join } from 'node:path';
4
+ import path$2 from 'node:path';
5
5
  import fs$3 from 'node:fs';
6
6
  import process$1$1 from 'node:process';
7
- import { b as be, a as commonjsGlobal, t as templates, c as create$1 } from './_commonjsHelpers-n7_cr1vO.js';
8
- import { u as up$1, d as dedent, p as parseJson, b as parseScript, e as imports, f as common, g as exports$1, o as object$1, v as variables, _ as _function, h as parseSvelte, j as array$1, w as walk$1, k as kit, l as addFromString, E as Element, m as index, n as parseHtml, q as parseHtml$1, A as AtRule2, s as parseCss, t as pc, x as intro, y as outro, z as cancel, B as box, C as multiselect, D as isCancel, F as log$1, G as confirm, c as createWorkspace, H as note, I as select, J as text, K as packageManagerPrompt, L as installDependencies, M as formatFiles, i as installPackages, a as createOrUpdateFiles, r as resolveCommand, N as spinner, O as getHighlighter, P as detectSync, Q as getUserAgent, R as group, S as from$1 } from './processor-SieBGHed.js';
7
+ import { u as up$1, d as dedent, p as parseJson, a as parseScript, b as imports, c as common, e as exports$1, o as object$1, v as variables, _ as _function, f as parseSvelte, g as array$1, w as walk$1, k as kit, h as addFromString, E as Element, j as index, l as parseHtml, m as parseHtml$1, A as AtRule2, n as parseCss, q as pc, r as intro, s as outro, t as log$1, x as cancel, y as box, z as multiselect, B as isCancel, C as confirm, D as createWorkspace, F as setupAddons, G as note, H as select, I as text, J as packageManagerPrompt, K as applyAddons, L as installDependencies, M as formatFiles, N as spinner, O as getHighlighter, P as detectSync, Q as getUserAgent, R as group, S as resolveCommand, T as from$1 } from './install-aMzn70r6.js';
9
8
  import 'node:readline';
10
9
  import 'node:tty';
11
- import { pipeline as pipeline$1 } from 'node:stream/promises';
12
10
  import { createGunzip } from 'node:zlib';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { pipeline as pipeline$1 } from 'node:stream/promises';
13
+ import { a as commonjsGlobal, b as be, t as templates, c as create$1 } from './main-UNazaUHM.js';
13
14
  import require$$5 from 'events';
14
15
  import require$$1$1 from 'fs';
15
16
  import require$$1$1$1 from 'path';
16
- import { fileURLToPath } from 'node:url';
17
17
  import 'node:module';
18
+ import 'os';
19
+ import 'url';
20
+ import 'node:fs/promises';
18
21
  import 'child_process';
19
22
  import 'process';
20
23
  import 'stream';
21
24
  import 'readline';
22
- import 'node:fs/promises';
23
- import 'os';
24
- import 'url';
25
25
 
26
26
  var name = "sv";
27
- var version = "0.6.2";
27
+ var version = "0.6.3";
28
28
  var type = "module";
29
29
  var description = "A CLI for creating and updating SvelteKit projects";
30
30
  var license = "MIT";
@@ -54,7 +54,7 @@ var exports = {
54
54
  }
55
55
  };
56
56
  var devDependencies = {
57
- "@sveltejs/adders": "workspace:*",
57
+ "@sveltejs/addons": "workspace:*",
58
58
  "@sveltejs/clack-prompts": "workspace:*",
59
59
  "@sveltejs/cli-core": "workspace:*",
60
60
  "@sveltejs/create": "workspace:*",
@@ -4345,10 +4345,10 @@ function up(options) {
4345
4345
  return up$1("package.json", options);
4346
4346
  }
4347
4347
 
4348
- function defineAdder(config) {
4348
+ function defineAddon(config) {
4349
4349
  return config;
4350
4350
  }
4351
- function defineAdderOptions(options) {
4351
+ function defineAddonOptions(options) {
4352
4352
  return options;
4353
4353
  }
4354
4354
  var eastasianwidth = { exports: {} };
@@ -4880,7 +4880,7 @@ const PORTS = {
4880
4880
  postgresql: "5432",
4881
4881
  sqlite: ""
4882
4882
  };
4883
- const options$4 = defineAdderOptions({
4883
+ const options$4 = defineAddonOptions({
4884
4884
  database: {
4885
4885
  question: "Which database would you like to use?",
4886
4886
  type: "select",
@@ -4932,73 +4932,31 @@ const options$4 = defineAdderOptions({
4932
4932
  condition: ({ database, mysql, postgresql }) => database === "mysql" && mysql === "mysql2" || database === "postgresql" && postgresql === "postgres.js"
4933
4933
  }
4934
4934
  });
4935
- var drizzle = defineAdder({
4935
+ var drizzle = defineAddon({
4936
4936
  id: "drizzle",
4937
- environments: { svelte: false, kit: true },
4938
4937
  homepage: "https://orm.drizzle.team",
4939
4938
  options: options$4,
4940
- packages: [
4941
- { name: "drizzle-orm", version: "^0.33.0", dev: false },
4942
- { name: "drizzle-kit", version: "^0.22.0", dev: true },
4943
- // MySQL
4944
- {
4945
- name: "mysql2",
4946
- version: "^3.11.0",
4947
- dev: false,
4948
- condition: ({ options: options2 }) => options2.mysql === "mysql2"
4949
- },
4950
- {
4951
- name: "@planetscale/database",
4952
- version: "^1.18.0",
4953
- dev: false,
4954
- condition: ({ options: options2 }) => options2.mysql === "planetscale"
4955
- },
4956
- // PostgreSQL
4957
- {
4958
- name: "@neondatabase/serverless",
4959
- version: "^0.9.4",
4960
- dev: false,
4961
- condition: ({ options: options2 }) => options2.postgresql === "neon"
4962
- },
4963
- {
4964
- name: "postgres",
4965
- version: "^3.4.4",
4966
- dev: false,
4967
- condition: ({ options: options2 }) => options2.postgresql === "postgres.js"
4968
- },
4969
- // SQLite
4970
- {
4971
- name: "better-sqlite3",
4972
- version: "^11.1.2",
4973
- dev: false,
4974
- condition: ({ options: options2 }) => options2.sqlite === "better-sqlite3"
4975
- },
4976
- {
4977
- name: "@types/better-sqlite3",
4978
- version: "^7.6.11",
4979
- dev: true,
4980
- condition: ({ options: options2 }) => options2.sqlite === "better-sqlite3"
4981
- },
4982
- {
4983
- name: "@libsql/client",
4984
- version: "^0.9.0",
4985
- dev: false,
4986
- condition: ({ options: options2 }) => options2.sqlite === "libsql" || options2.sqlite === "turso"
4987
- }
4988
- ],
4989
- files: [
4990
- {
4991
- name: () => ".env",
4992
- content: generateEnvFileContent
4993
- },
4994
- {
4995
- name: () => ".env.example",
4996
- content: generateEnvFileContent
4997
- },
4998
- {
4999
- name: () => "docker-compose.yml",
5000
- condition: ({ options: options2 }) => options2.docker && (options2.mysql === "mysql2" || options2.postgresql === "postgres.js"),
5001
- content: ({ content, options: options2 }) => {
4939
+ setup: ({ kit, unsupported }) => {
4940
+ if (!kit) unsupported("Requires SvelteKit");
4941
+ },
4942
+ run: ({ sv, typescript, options: options2, kit }) => {
4943
+ const ext = typescript ? "ts" : "js";
4944
+ sv.dependency("drizzle-orm", "^0.33.0");
4945
+ sv.devDependency("drizzle-kit", "^0.22.0");
4946
+ if (options2.mysql === "mysql2") sv.dependency("mysql2", "^3.11.0");
4947
+ if (options2.mysql === "planetscale") sv.dependency("@planetscale/database", "^1.18.0");
4948
+ if (options2.postgresql === "neon") sv.dependency("@neondatabase/serverless", "^0.9.4");
4949
+ if (options2.postgresql === "postgres.js") sv.dependency("postgres", "^3.4.4");
4950
+ if (options2.sqlite === "better-sqlite3") {
4951
+ sv.dependency("better-sqlite3", "^11.1.2");
4952
+ sv.devDependency("@types/better-sqlite3", "^7.6.11");
4953
+ }
4954
+ if (options2.sqlite === "libsql" || options2.sqlite === "turso")
4955
+ sv.dependency("@libsql/client", "^0.9.0");
4956
+ sv.file(".env", (content) => generateEnvFileContent(content, options2));
4957
+ sv.file(".env.example", (content) => generateEnvFileContent(content, options2));
4958
+ if (options2.docker && (options2.mysql === "mysql2" || options2.postgresql === "postgres.js")) {
4959
+ sv.file("docker-compose.yml", (content) => {
5002
4960
  if (content.length > 0) return content;
5003
4961
  const imageName = options2.database === "mysql" ? "mysql" : "postgres";
5004
4962
  const port = PORTS[options2.database];
@@ -5029,177 +4987,160 @@ var drizzle = defineAdder({
5029
4987
  environment: ${dbSpecificContent}
5030
4988
  `;
5031
4989
  return content;
5032
- }
5033
- },
5034
- {
5035
- name: () => "package.json",
5036
- content: ({ content, options: options2 }) => {
5037
- const { data, generateCode } = parseJson(content);
5038
- data.scripts ?? (data.scripts = {});
5039
- const scripts = data.scripts;
5040
- if (options2.docker) scripts["db:start"] ?? (scripts["db:start"] = "docker compose up");
5041
- scripts["db:push"] ?? (scripts["db:push"] = "drizzle-kit push");
5042
- scripts["db:migrate"] ?? (scripts["db:migrate"] = "drizzle-kit migrate");
5043
- scripts["db:studio"] ?? (scripts["db:studio"] = "drizzle-kit studio");
5044
- return generateCode();
5045
- }
5046
- },
5047
- {
5048
- // Adds the db file to the gitignore if an ignore is present
5049
- name: () => ".gitignore",
5050
- condition: ({ options: options2 }) => options2.database === "sqlite",
5051
- content: ({ content }) => {
4990
+ });
4991
+ }
4992
+ sv.file("package.json", (content) => {
4993
+ const { data, generateCode } = parseJson(content);
4994
+ data.scripts ?? (data.scripts = {});
4995
+ const scripts = data.scripts;
4996
+ if (options2.docker) scripts["db:start"] ?? (scripts["db:start"] = "docker compose up");
4997
+ scripts["db:push"] ?? (scripts["db:push"] = "drizzle-kit push");
4998
+ scripts["db:migrate"] ?? (scripts["db:migrate"] = "drizzle-kit migrate");
4999
+ scripts["db:studio"] ?? (scripts["db:studio"] = "drizzle-kit studio");
5000
+ return generateCode();
5001
+ });
5002
+ if (options2.database === "sqlite") {
5003
+ sv.file(".gitignore", (content) => {
5052
5004
  if (content.length === 0) return content;
5053
5005
  if (!content.includes("\n*.db")) {
5054
5006
  content = content.trimEnd() + "\n\n# SQLite\n*.db";
5055
5007
  }
5056
5008
  return content;
5057
- }
5058
- },
5059
- {
5060
- name: ({ typescript }) => `drizzle.config.${typescript ? "ts" : "js"}`,
5061
- content: ({ options: options2, content, typescript }) => {
5062
- const { ast, generateCode } = parseScript(content);
5063
- imports.addNamed(ast, "drizzle-kit", { defineConfig: "defineConfig" });
5064
- const envCheckStatement = common.statementFromString(
5065
- "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
5066
- );
5067
- common.addStatement(ast, envCheckStatement);
5068
- const fallback = common.expressionFromString("defineConfig({})");
5069
- const { value: exportDefault } = exports$1.defaultExport(ast, fallback);
5070
- if (exportDefault.type !== "CallExpression") return content;
5071
- const objExpression = exportDefault.arguments?.[0];
5072
- if (!objExpression || objExpression.type !== "ObjectExpression") return content;
5073
- const driver = options2.sqlite === "turso" ? common.createLiteral("turso") : void 0;
5074
- const authToken = options2.sqlite === "turso" ? common.expressionFromString("process.env.DATABASE_AUTH_TOKEN") : void 0;
5075
- object$1.properties(objExpression, {
5076
- schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? "ts" : "js"}`),
5077
- dbCredentials: object$1.create({
5078
- url: common.expressionFromString("process.env.DATABASE_URL"),
5079
- authToken
5080
- }),
5081
- verbose: { type: "BooleanLiteral", value: true },
5082
- strict: { type: "BooleanLiteral", value: true },
5083
- driver
5009
+ });
5010
+ }
5011
+ sv.file(`drizzle.config.${ext}`, (content) => {
5012
+ const { ast, generateCode } = parseScript(content);
5013
+ imports.addNamed(ast, "drizzle-kit", { defineConfig: "defineConfig" });
5014
+ const envCheckStatement = common.statementFromString(
5015
+ "if (!process.env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
5016
+ );
5017
+ common.addStatement(ast, envCheckStatement);
5018
+ const fallback = common.expressionFromString("defineConfig({})");
5019
+ const { value: exportDefault } = exports$1.defaultExport(ast, fallback);
5020
+ if (exportDefault.type !== "CallExpression") return content;
5021
+ const objExpression = exportDefault.arguments?.[0];
5022
+ if (!objExpression || objExpression.type !== "ObjectExpression") return content;
5023
+ const driver = options2.sqlite === "turso" ? common.createLiteral("turso") : void 0;
5024
+ const authToken = options2.sqlite === "turso" ? common.expressionFromString("process.env.DATABASE_AUTH_TOKEN") : void 0;
5025
+ object$1.properties(objExpression, {
5026
+ schema: common.createLiteral(`./src/lib/server/db/schema.${typescript ? "ts" : "js"}`),
5027
+ dbCredentials: object$1.create({
5028
+ url: common.expressionFromString("process.env.DATABASE_URL"),
5029
+ authToken
5030
+ }),
5031
+ verbose: { type: "BooleanLiteral", value: true },
5032
+ strict: { type: "BooleanLiteral", value: true },
5033
+ driver
5034
+ });
5035
+ object$1.overrideProperties(objExpression, {
5036
+ dialect: common.createLiteral(options2.database)
5037
+ });
5038
+ if (options2.database !== "sqlite") object$1.removeProperty(objExpression, "driver");
5039
+ return generateCode();
5040
+ });
5041
+ sv.file(`${kit?.libDirectory}/server/db/schema.${ext}`, (content) => {
5042
+ const { ast, generateCode } = parseScript(content);
5043
+ let userSchemaExpression;
5044
+ if (options2.database === "sqlite") {
5045
+ imports.addNamed(ast, "drizzle-orm/sqlite-core", {
5046
+ sqliteTable: "sqliteTable",
5047
+ text: "text",
5048
+ integer: "integer"
5084
5049
  });
5085
- object$1.overrideProperties(objExpression, {
5086
- dialect: common.createLiteral(options2.database)
5050
+ userSchemaExpression = common.expressionFromString(`sqliteTable('user', {
5051
+ id: integer('id').primaryKey(),
5052
+ age: integer('age')
5053
+ })`);
5054
+ }
5055
+ if (options2.database === "mysql") {
5056
+ imports.addNamed(ast, "drizzle-orm/mysql-core", {
5057
+ mysqlTable: "mysqlTable",
5058
+ serial: "serial",
5059
+ text: "text",
5060
+ int: "int"
5087
5061
  });
5088
- if (options2.database !== "sqlite") object$1.removeProperty(objExpression, "driver");
5089
- return generateCode();
5090
- }
5091
- },
5092
- {
5093
- name: ({ kit, typescript }) => `${kit?.libDirectory}/server/db/schema.${typescript ? "ts" : "js"}`,
5094
- content: ({ content, options: options2 }) => {
5095
- const { ast, generateCode } = parseScript(content);
5096
- let userSchemaExpression;
5097
- if (options2.database === "sqlite") {
5098
- imports.addNamed(ast, "drizzle-orm/sqlite-core", {
5099
- sqliteTable: "sqliteTable",
5100
- text: "text",
5101
- integer: "integer"
5102
- });
5103
- userSchemaExpression = common.expressionFromString(`sqliteTable('user', {
5104
- id: integer('id').primaryKey(),
5105
- age: integer('age')
5106
- })`);
5107
- }
5108
- if (options2.database === "mysql") {
5109
- imports.addNamed(ast, "drizzle-orm/mysql-core", {
5110
- mysqlTable: "mysqlTable",
5111
- serial: "serial",
5112
- text: "text",
5113
- int: "int"
5114
- });
5115
- userSchemaExpression = common.expressionFromString(`mysqlTable('user', {
5116
- id: serial('id').primaryKey(),
5117
- age: int('age'),
5118
- })`);
5119
- }
5120
- if (options2.database === "postgresql") {
5121
- imports.addNamed(ast, "drizzle-orm/pg-core", {
5122
- pgTable: "pgTable",
5123
- serial: "serial",
5124
- text: "text",
5125
- integer: "integer"
5126
- });
5127
- userSchemaExpression = common.expressionFromString(`pgTable('user', {
5128
- id: serial('id').primaryKey(),
5129
- age: integer('age'),
5130
- })`);
5131
- }
5132
- if (!userSchemaExpression) throw new Error("unreachable state...");
5133
- const userIdentifier = variables.declaration(ast, "const", "user", userSchemaExpression);
5134
- exports$1.namedExport(ast, "user", userIdentifier);
5135
- return generateCode();
5136
- }
5137
- },
5138
- {
5139
- name: ({ kit, typescript }) => `${kit?.libDirectory}/server/db/index.${typescript ? "ts" : "js"}`,
5140
- content: ({ content, options: options2 }) => {
5141
- const { ast, generateCode } = parseScript(content);
5142
- imports.addNamed(ast, "$env/dynamic/private", { env: "env" });
5143
- const dbURLCheck = common.statementFromString(
5144
- "if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
5145
- );
5146
- common.addStatement(ast, dbURLCheck);
5147
- let clientExpression;
5148
- if (options2.sqlite === "better-sqlite3") {
5149
- imports.addDefault(ast, "better-sqlite3", "Database");
5150
- imports.addNamed(ast, "drizzle-orm/better-sqlite3", { drizzle: "drizzle" });
5151
- clientExpression = common.expressionFromString("new Database(env.DATABASE_URL)");
5152
- }
5153
- if (options2.sqlite === "libsql" || options2.sqlite === "turso") {
5154
- imports.addNamed(ast, "@libsql/client", { createClient: "createClient" });
5155
- imports.addNamed(ast, "drizzle-orm/libsql", { drizzle: "drizzle" });
5156
- if (options2.sqlite === "turso") {
5157
- imports.addNamed(ast, "$app/environment", { dev: "dev" });
5158
- const authTokenCheck = common.statementFromString(
5159
- "if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');"
5160
- );
5161
- common.addStatement(ast, authTokenCheck);
5162
- clientExpression = common.expressionFromString(
5163
- "createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN })"
5164
- );
5165
- } else {
5166
- clientExpression = common.expressionFromString(
5167
- "createClient({ url: env.DATABASE_URL })"
5168
- );
5169
- }
5170
- }
5171
- if (options2.mysql === "mysql2") {
5172
- imports.addDefault(ast, "mysql2/promise", "mysql");
5173
- imports.addNamed(ast, "drizzle-orm/mysql2", { drizzle: "drizzle" });
5062
+ userSchemaExpression = common.expressionFromString(`mysqlTable('user', {
5063
+ id: serial('id').primaryKey(),
5064
+ age: int('age'),
5065
+ })`);
5066
+ }
5067
+ if (options2.database === "postgresql") {
5068
+ imports.addNamed(ast, "drizzle-orm/pg-core", {
5069
+ pgTable: "pgTable",
5070
+ serial: "serial",
5071
+ text: "text",
5072
+ integer: "integer"
5073
+ });
5074
+ userSchemaExpression = common.expressionFromString(`pgTable('user', {
5075
+ id: serial('id').primaryKey(),
5076
+ age: integer('age'),
5077
+ })`);
5078
+ }
5079
+ if (!userSchemaExpression) throw new Error("unreachable state...");
5080
+ const userIdentifier = variables.declaration(ast, "const", "user", userSchemaExpression);
5081
+ exports$1.namedExport(ast, "user", userIdentifier);
5082
+ return generateCode();
5083
+ });
5084
+ sv.file(`${kit?.libDirectory}/server/db/index.${ext}`, (content) => {
5085
+ const { ast, generateCode } = parseScript(content);
5086
+ imports.addNamed(ast, "$env/dynamic/private", { env: "env" });
5087
+ const dbURLCheck = common.statementFromString(
5088
+ "if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');"
5089
+ );
5090
+ common.addStatement(ast, dbURLCheck);
5091
+ let clientExpression;
5092
+ if (options2.sqlite === "better-sqlite3") {
5093
+ imports.addDefault(ast, "better-sqlite3", "Database");
5094
+ imports.addNamed(ast, "drizzle-orm/better-sqlite3", { drizzle: "drizzle" });
5095
+ clientExpression = common.expressionFromString("new Database(env.DATABASE_URL)");
5096
+ }
5097
+ if (options2.sqlite === "libsql" || options2.sqlite === "turso") {
5098
+ imports.addNamed(ast, "@libsql/client", { createClient: "createClient" });
5099
+ imports.addNamed(ast, "drizzle-orm/libsql", { drizzle: "drizzle" });
5100
+ if (options2.sqlite === "turso") {
5101
+ imports.addNamed(ast, "$app/environment", { dev: "dev" });
5102
+ const authTokenCheck = common.statementFromString(
5103
+ "if (!dev && !env.DATABASE_AUTH_TOKEN) throw new Error('DATABASE_AUTH_TOKEN is not set');"
5104
+ );
5105
+ common.addStatement(ast, authTokenCheck);
5174
5106
  clientExpression = common.expressionFromString(
5175
- "await mysql.createConnection(env.DATABASE_URL)"
5107
+ "createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN })"
5176
5108
  );
5109
+ } else {
5110
+ clientExpression = common.expressionFromString("createClient({ url: env.DATABASE_URL })");
5177
5111
  }
5178
- if (options2.mysql === "planetscale") {
5179
- imports.addNamed(ast, "@planetscale/database", { Client: "Client" });
5180
- imports.addNamed(ast, "drizzle-orm/planetscale-serverless", { drizzle: "drizzle" });
5181
- clientExpression = common.expressionFromString("new Client({ url: env.DATABASE_URL })");
5182
- }
5183
- if (options2.postgresql === "neon") {
5184
- imports.addNamed(ast, "@neondatabase/serverless", { neon: "neon" });
5185
- imports.addNamed(ast, "drizzle-orm/neon-http", { drizzle: "drizzle" });
5186
- clientExpression = common.expressionFromString("neon(env.DATABASE_URL)");
5187
- }
5188
- if (options2.postgresql === "postgres.js") {
5189
- imports.addDefault(ast, "postgres", "postgres");
5190
- imports.addNamed(ast, "drizzle-orm/postgres-js", { drizzle: "drizzle" });
5191
- clientExpression = common.expressionFromString("postgres(env.DATABASE_URL)");
5192
- }
5193
- if (!clientExpression) throw new Error("unreachable state...");
5194
- const clientIdentifier = variables.declaration(ast, "const", "client", clientExpression);
5195
- common.addStatement(ast, clientIdentifier);
5196
- const drizzleCall = _function.callByIdentifier("drizzle", ["client"]);
5197
- const db = variables.declaration(ast, "const", "db", drizzleCall);
5198
- exports$1.namedExport(ast, "db", db);
5199
- return generateCode();
5200
5112
  }
5201
- }
5202
- ],
5113
+ if (options2.mysql === "mysql2") {
5114
+ imports.addDefault(ast, "mysql2/promise", "mysql");
5115
+ imports.addNamed(ast, "drizzle-orm/mysql2", { drizzle: "drizzle" });
5116
+ clientExpression = common.expressionFromString(
5117
+ "await mysql.createConnection(env.DATABASE_URL)"
5118
+ );
5119
+ }
5120
+ if (options2.mysql === "planetscale") {
5121
+ imports.addNamed(ast, "@planetscale/database", { Client: "Client" });
5122
+ imports.addNamed(ast, "drizzle-orm/planetscale-serverless", { drizzle: "drizzle" });
5123
+ clientExpression = common.expressionFromString("new Client({ url: env.DATABASE_URL })");
5124
+ }
5125
+ if (options2.postgresql === "neon") {
5126
+ imports.addNamed(ast, "@neondatabase/serverless", { neon: "neon" });
5127
+ imports.addNamed(ast, "drizzle-orm/neon-http", { drizzle: "drizzle" });
5128
+ clientExpression = common.expressionFromString("neon(env.DATABASE_URL)");
5129
+ }
5130
+ if (options2.postgresql === "postgres.js") {
5131
+ imports.addDefault(ast, "postgres", "postgres");
5132
+ imports.addNamed(ast, "drizzle-orm/postgres-js", { drizzle: "drizzle" });
5133
+ clientExpression = common.expressionFromString("postgres(env.DATABASE_URL)");
5134
+ }
5135
+ if (!clientExpression) throw new Error("unreachable state...");
5136
+ const clientIdentifier = variables.declaration(ast, "const", "client", clientExpression);
5137
+ common.addStatement(ast, clientIdentifier);
5138
+ const drizzleCall = _function.callByIdentifier("drizzle", ["client"]);
5139
+ const db = variables.declaration(ast, "const", "db", drizzleCall);
5140
+ exports$1.namedExport(ast, "db", db);
5141
+ return generateCode();
5142
+ });
5143
+ },
5203
5144
  nextSteps: ({ options: options2, highlighter, packageManager }) => {
5204
5145
  const steps = [
5205
5146
  `You will need to set ${highlighter.env("DATABASE_URL")} in your production environment`
@@ -5215,7 +5156,7 @@ var drizzle = defineAdder({
5215
5156
  return steps;
5216
5157
  }
5217
5158
  });
5218
- function generateEnvFileContent({ content, options: opts }) {
5159
+ function generateEnvFileContent(content, opts) {
5219
5160
  const DB_URL_KEY = "DATABASE_URL";
5220
5161
  if (opts.docker) {
5221
5162
  const protocol = opts.database === "mysql" ? "mysql" : "postgres";
@@ -5265,7 +5206,7 @@ function appendEnvContent(existing, content) {
5265
5206
  return withNewLine + content + "\n";
5266
5207
  }
5267
5208
 
5268
- function addEslintConfigPrettier({ content }) {
5209
+ function addEslintConfigPrettier(content) {
5269
5210
  const { ast, generateCode } = parseScript(content);
5270
5211
  const importNodes = ast.body.filter((n) => n.type === "ImportDeclaration");
5271
5212
  const sveltePluginImport = importNodes.find(
@@ -5304,7 +5245,7 @@ function addEslintConfigPrettier({ content }) {
5304
5245
  }
5305
5246
  return generateCode();
5306
5247
  }
5307
- function addToDemoPage({ content }, path) {
5248
+ function addToDemoPage(content, path) {
5308
5249
  const { template, generateCode } = parseSvelte(content);
5309
5250
  for (const node of template.ast.childNodes) {
5310
5251
  if (node.type === "tag" && node.attribs["href"] === `/demo/${path}`) {
@@ -5316,125 +5257,101 @@ function addToDemoPage({ content }, path) {
5316
5257
  return generateCode({ template: src });
5317
5258
  }
5318
5259
 
5319
- var eslint = defineAdder({
5260
+ var eslint = defineAddon({
5320
5261
  id: "eslint",
5321
- environments: { svelte: true, kit: true },
5322
5262
  homepage: "https://eslint.org",
5323
5263
  options: {},
5324
- packages: [
5325
- { name: "eslint", version: "^9.7.0", dev: true },
5326
- { name: "@types/eslint", version: "^9.6.0", dev: true },
5327
- { name: "globals", version: "^15.0.0", dev: true },
5328
- {
5329
- name: "typescript-eslint",
5330
- version: "^8.0.0",
5331
- dev: true,
5332
- condition: ({ typescript }) => typescript
5333
- },
5334
- { name: "eslint-plugin-svelte", version: "^2.36.0", dev: true },
5335
- {
5336
- name: "eslint-config-prettier",
5337
- version: "^9.1.0",
5338
- dev: true,
5339
- condition: ({ dependencyVersion }) => Boolean(dependencyVersion("prettier"))
5340
- }
5341
- ],
5342
- files: [
5343
- {
5344
- name: () => "package.json",
5345
- content: ({ content }) => {
5346
- const { data, generateCode } = parseJson(content);
5347
- data.scripts ?? (data.scripts = {});
5348
- const scripts = data.scripts;
5349
- const LINT_CMD = "eslint .";
5350
- scripts["lint"] ?? (scripts["lint"] = LINT_CMD);
5351
- if (!scripts["lint"].includes(LINT_CMD)) scripts["lint"] += ` && ${LINT_CMD}`;
5352
- return generateCode();
5353
- }
5354
- },
5355
- {
5356
- name: () => ".vscode/settings.json",
5357
- // we'll only want to run this step if the file exists
5358
- condition: ({ cwd }) => fs$3.existsSync(path$2.join(cwd, ".vscode", "settings.json")),
5359
- content: ({ content }) => {
5360
- const { data, generateCode } = parseJson(content);
5361
- const validate = data["eslint.validate"];
5362
- if (validate && !validate.includes("svelte")) {
5363
- validate.push("svelte");
5364
- }
5365
- return generateCode();
5366
- }
5367
- },
5368
- {
5369
- name: () => "eslint.config.js",
5370
- content: ({ content, typescript }) => {
5371
- const { ast, generateCode } = parseScript(content);
5372
- const eslintConfigs = [];
5373
- const jsConfig = common.expressionFromString("js.configs.recommended");
5374
- eslintConfigs.push(jsConfig);
5375
- if (typescript) {
5376
- const tsConfig = common.expressionFromString("ts.configs.recommended");
5377
- eslintConfigs.push(common.createSpreadElement(tsConfig));
5378
- }
5379
- const svelteConfig = common.expressionFromString('svelte.configs["flat/recommended"]');
5380
- eslintConfigs.push(common.createSpreadElement(svelteConfig));
5381
- const globalsBrowser = common.createSpreadElement(
5382
- common.expressionFromString("globals.browser")
5383
- );
5384
- const globalsNode = common.createSpreadElement(common.expressionFromString("globals.node"));
5385
- const globalsObjLiteral = object$1.createEmpty();
5386
- globalsObjLiteral.properties = [globalsBrowser, globalsNode];
5387
- const globalsConfig = object$1.create({
5264
+ run: ({ sv, typescript, dependencyVersion }) => {
5265
+ const prettierInstalled = Boolean(dependencyVersion("prettier"));
5266
+ sv.devDependency("eslint", "^9.7.0");
5267
+ sv.devDependency("@types/eslint", "^9.6.0");
5268
+ sv.devDependency("globals", "^15.0.0");
5269
+ sv.devDependency("eslint-plugin-svelte", "^2.36.0");
5270
+ if (typescript) sv.devDependency("typescript-eslint", "^8.0.0");
5271
+ if (prettierInstalled) sv.devDependency("eslint-config-prettier", "^9.1.0");
5272
+ sv.file("package.json", (content) => {
5273
+ const { data, generateCode } = parseJson(content);
5274
+ data.scripts ?? (data.scripts = {});
5275
+ const scripts = data.scripts;
5276
+ const LINT_CMD = "eslint .";
5277
+ scripts["lint"] ?? (scripts["lint"] = LINT_CMD);
5278
+ if (!scripts["lint"].includes(LINT_CMD)) scripts["lint"] += ` && ${LINT_CMD}`;
5279
+ return generateCode();
5280
+ });
5281
+ sv.file(".vscode/settings.json", (content) => {
5282
+ if (!content) return content;
5283
+ const { data, generateCode } = parseJson(content);
5284
+ const validate = data["eslint.validate"];
5285
+ if (validate && !validate.includes("svelte")) {
5286
+ validate.push("svelte");
5287
+ }
5288
+ return generateCode();
5289
+ });
5290
+ sv.file("eslint.config.js", (content) => {
5291
+ const { ast, generateCode } = parseScript(content);
5292
+ const eslintConfigs = [];
5293
+ const jsConfig = common.expressionFromString("js.configs.recommended");
5294
+ eslintConfigs.push(jsConfig);
5295
+ if (typescript) {
5296
+ const tsConfig = common.expressionFromString("ts.configs.recommended");
5297
+ eslintConfigs.push(common.createSpreadElement(tsConfig));
5298
+ }
5299
+ const svelteConfig = common.expressionFromString('svelte.configs["flat/recommended"]');
5300
+ eslintConfigs.push(common.createSpreadElement(svelteConfig));
5301
+ const globalsBrowser = common.createSpreadElement(
5302
+ common.expressionFromString("globals.browser")
5303
+ );
5304
+ const globalsNode = common.createSpreadElement(common.expressionFromString("globals.node"));
5305
+ const globalsObjLiteral = object$1.createEmpty();
5306
+ globalsObjLiteral.properties = [globalsBrowser, globalsNode];
5307
+ const globalsConfig = object$1.create({
5308
+ languageOptions: object$1.create({
5309
+ globals: globalsObjLiteral
5310
+ })
5311
+ });
5312
+ eslintConfigs.push(globalsConfig);
5313
+ if (typescript) {
5314
+ const svelteTSParserConfig = object$1.create({
5315
+ files: common.expressionFromString('["**/*.svelte"]'),
5388
5316
  languageOptions: object$1.create({
5389
- globals: globalsObjLiteral
5390
- })
5391
- });
5392
- eslintConfigs.push(globalsConfig);
5393
- if (typescript) {
5394
- const svelteTSParserConfig = object$1.create({
5395
- files: common.expressionFromString('["**/*.svelte"]'),
5396
- languageOptions: object$1.create({
5397
- parserOptions: object$1.create({
5398
- parser: common.expressionFromString("ts.parser")
5399
- })
5317
+ parserOptions: object$1.create({
5318
+ parser: common.expressionFromString("ts.parser")
5400
5319
  })
5401
- });
5402
- eslintConfigs.push(svelteTSParserConfig);
5403
- }
5404
- const ignoresConfig = object$1.create({
5405
- ignores: common.expressionFromString('["build/", ".svelte-kit/", "dist/"]')
5320
+ })
5406
5321
  });
5407
- eslintConfigs.push(ignoresConfig);
5408
- let exportExpression;
5409
- if (typescript) {
5410
- const tsConfigCall = _function.call("ts.config", []);
5411
- tsConfigCall.arguments.push(...eslintConfigs);
5412
- exportExpression = tsConfigCall;
5413
- } else {
5414
- const eslintArray = array$1.createEmpty();
5415
- eslintConfigs.map((x) => array$1.push(eslintArray, x));
5416
- exportExpression = eslintArray;
5417
- }
5418
- const defaultExport = exports$1.defaultExport(ast, exportExpression);
5419
- if (defaultExport.value !== exportExpression) {
5420
- log.warn("An eslint config is already defined. Skipping initialization.");
5421
- return content;
5422
- }
5423
- if (!typescript)
5424
- common.addJsDocTypeComment(defaultExport.astNode, "import('eslint').Linter.Config[]");
5425
- if (typescript) imports.addDefault(ast, "typescript-eslint", "ts");
5426
- imports.addDefault(ast, "globals", "globals");
5427
- imports.addDefault(ast, "eslint-plugin-svelte", "svelte");
5428
- imports.addDefault(ast, "@eslint/js", "js");
5429
- return generateCode();
5322
+ eslintConfigs.push(svelteTSParserConfig);
5430
5323
  }
5431
- },
5432
- {
5433
- name: () => "eslint.config.js",
5434
- condition: ({ dependencyVersion }) => Boolean(dependencyVersion("prettier")),
5435
- content: addEslintConfigPrettier
5324
+ const ignoresConfig = object$1.create({
5325
+ ignores: common.expressionFromString('["build/", ".svelte-kit/", "dist/"]')
5326
+ });
5327
+ eslintConfigs.push(ignoresConfig);
5328
+ let exportExpression;
5329
+ if (typescript) {
5330
+ const tsConfigCall = _function.call("ts.config", []);
5331
+ tsConfigCall.arguments.push(...eslintConfigs);
5332
+ exportExpression = tsConfigCall;
5333
+ } else {
5334
+ const eslintArray = array$1.createEmpty();
5335
+ eslintConfigs.map((x) => array$1.push(eslintArray, x));
5336
+ exportExpression = eslintArray;
5337
+ }
5338
+ const defaultExport = exports$1.defaultExport(ast, exportExpression);
5339
+ if (defaultExport.value !== exportExpression) {
5340
+ log.warn("An eslint config is already defined. Skipping initialization.");
5341
+ return content;
5342
+ }
5343
+ if (!typescript)
5344
+ common.addJsDocTypeComment(defaultExport.astNode, "import('eslint').Linter.Config[]");
5345
+ if (typescript) imports.addDefault(ast, "typescript-eslint", "ts");
5346
+ imports.addDefault(ast, "globals", "globals");
5347
+ imports.addDefault(ast, "eslint-plugin-svelte", "svelte");
5348
+ imports.addDefault(ast, "@eslint/js", "js");
5349
+ return generateCode();
5350
+ });
5351
+ if (prettierInstalled) {
5352
+ sv.file("eslint.config.js", addEslintConfigPrettier);
5436
5353
  }
5437
- ]
5354
+ }
5438
5355
  });
5439
5356
 
5440
5357
  const comma = ','.charCodeAt(0);
@@ -6785,8 +6702,8 @@ class MagicString {
6785
6702
  }
6786
6703
 
6787
6704
  var __freeze = Object.freeze;
6788
- var __defProp = Object.defineProperty;
6789
- var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(cooked.slice()) }));
6705
+ var __defProp$1 = Object.defineProperty;
6706
+ var __template = (cooked, raw) => __freeze(__defProp$1(cooked, "raw", { value: __freeze(cooked.slice()) }));
6790
6707
  var _a, _b;
6791
6708
  const TABLE_TYPE = {
6792
6709
  mysql: "mysqlTable",
@@ -6795,316 +6712,302 @@ const TABLE_TYPE = {
6795
6712
  };
6796
6713
  let drizzleDialect;
6797
6714
  let schemaPath;
6798
- const options$3 = defineAdderOptions({
6715
+ const options$3 = defineAddonOptions({
6799
6716
  demo: {
6800
6717
  type: "boolean",
6801
6718
  default: true,
6802
6719
  question: `Do you want to include a demo? ${picocolors.dim("(includes a login/register page)")}`
6803
6720
  }
6804
6721
  });
6805
- var lucia = defineAdder({
6722
+ var lucia = defineAddon({
6806
6723
  id: "lucia",
6807
- environments: { svelte: false, kit: true },
6808
6724
  homepage: "https://lucia-auth.com",
6809
6725
  options: options$3,
6810
- packages: [
6811
- { name: "@oslojs/crypto", version: "^1.0.1", dev: false },
6812
- { name: "@oslojs/encoding", version: "^1.1.0", dev: false },
6813
- // password hashing for demo
6814
- {
6815
- name: "@node-rs/argon2",
6816
- version: "^1.1.0",
6817
- condition: ({ options: options2 }) => options2.demo,
6818
- dev: false
6819
- }
6820
- ],
6821
- dependsOn: ["drizzle"],
6822
- files: [
6823
- {
6824
- name: ({ typescript }) => `drizzle.config.${typescript ? "ts" : "js"}`,
6825
- content: ({ content }) => {
6826
- const { ast, generateCode } = parseScript(content);
6827
- const isProp = (name, node) => node.key.type === "Identifier" && node.key.name === name;
6828
- walk$1.walk(ast, {}, {
6829
- ObjectProperty(node) {
6830
- if (isProp("dialect", node) && node.value.type === "StringLiteral") {
6831
- drizzleDialect = node.value.value;
6832
- }
6833
- if (isProp("schema", node) && node.value.type === "StringLiteral") {
6834
- schemaPath = node.value.value;
6835
- }
6726
+ setup: ({ kit, dependencyVersion, unsupported, dependsOn }) => {
6727
+ if (!kit) unsupported("Requires SvelteKit");
6728
+ if (!dependencyVersion("drizzle-orm")) dependsOn("drizzle");
6729
+ },
6730
+ run: ({ sv, typescript, options: options2, kit: kit$1, dependencyVersion }) => {
6731
+ const ext = typescript ? "ts" : "js";
6732
+ sv.dependency("@oslojs/crypto", "^1.0.1");
6733
+ sv.dependency("@oslojs/encoding", "^1.1.0");
6734
+ if (options2.demo) {
6735
+ sv.dependency("@node-rs/argon2", "^1.1.0");
6736
+ }
6737
+ sv.file(`drizzle.config.${ext}`, (content) => {
6738
+ const { ast, generateCode } = parseScript(content);
6739
+ const isProp = (name, node) => node.key.type === "Identifier" && node.key.name === name;
6740
+ walk$1.walk(ast, {}, {
6741
+ ObjectProperty(node) {
6742
+ if (isProp("dialect", node) && node.value.type === "StringLiteral") {
6743
+ drizzleDialect = node.value.value;
6836
6744
  }
6837
- });
6838
- if (!drizzleDialect) {
6839
- throw new Error("Failed to detect DB dialect in your `drizzle.config.[js|ts]` file");
6840
- }
6841
- if (!schemaPath) {
6842
- throw new Error("Failed to find schema path in your `drizzle.config.[js|ts]` file");
6843
- }
6844
- return generateCode();
6845
- }
6846
- },
6847
- {
6848
- name: () => schemaPath,
6849
- content: ({ content, options: options2, typescript }) => {
6850
- const { ast, generateCode } = parseScript(content);
6851
- const createTable = (name) => _function.call(TABLE_TYPE[drizzleDialect], [name]);
6852
- const userDecl = variables.declaration(ast, "const", "user", createTable("user"));
6853
- const sessionDecl = variables.declaration(ast, "const", "session", createTable("session"));
6854
- const user = exports$1.namedExport(ast, "user", userDecl);
6855
- const session = exports$1.namedExport(ast, "session", sessionDecl);
6856
- const userTable = getCallExpression(user);
6857
- const sessionTable = getCallExpression(session);
6858
- if (!userTable || !sessionTable) {
6859
- throw new Error("failed to find call expression of `user` or `session`");
6860
- }
6861
- if (userTable.arguments.length === 1) {
6862
- userTable.arguments.push(object$1.createEmpty());
6863
- }
6864
- if (sessionTable.arguments.length === 1) {
6865
- sessionTable.arguments.push(object$1.createEmpty());
6866
- }
6867
- const userAttributes = userTable.arguments[1];
6868
- const sessionAttributes = sessionTable.arguments[1];
6869
- if (userAttributes?.type !== "ObjectExpression" || sessionAttributes?.type !== "ObjectExpression") {
6870
- throw new Error("unexpected shape of `user` or `session` table definition");
6871
- }
6872
- if (drizzleDialect === "sqlite") {
6873
- imports.addNamed(ast, "drizzle-orm/sqlite-core", {
6874
- sqliteTable: "sqliteTable",
6875
- text: "text",
6876
- integer: "integer"
6877
- });
6878
- object$1.overrideProperties(userAttributes, {
6879
- id: common.expressionFromString("text('id').primaryKey()")
6880
- });
6881
- if (options2.demo) {
6882
- object$1.overrideProperties(userAttributes, {
6883
- username: common.expressionFromString("text('username').notNull().unique()"),
6884
- passwordHash: common.expressionFromString("text('password_hash').notNull()")
6885
- });
6745
+ if (isProp("schema", node) && node.value.type === "StringLiteral") {
6746
+ schemaPath = node.value.value;
6886
6747
  }
6887
- object$1.overrideProperties(sessionAttributes, {
6888
- id: common.expressionFromString("text('id').primaryKey()"),
6889
- userId: common.expressionFromString(
6890
- "text('user_id').notNull().references(() => user.id)"
6891
- ),
6892
- expiresAt: common.expressionFromString(
6893
- "integer('expires_at', { mode: 'timestamp' }).notNull()"
6894
- )
6895
- });
6896
6748
  }
6897
- if (drizzleDialect === "mysql") {
6898
- imports.addNamed(ast, "drizzle-orm/mysql-core", {
6899
- mysqlTable: "mysqlTable",
6900
- varchar: "varchar",
6901
- datetime: "datetime"
6902
- });
6749
+ });
6750
+ if (!drizzleDialect) {
6751
+ throw new Error("Failed to detect DB dialect in your `drizzle.config.[js|ts]` file");
6752
+ }
6753
+ if (!schemaPath) {
6754
+ throw new Error("Failed to find schema path in your `drizzle.config.[js|ts]` file");
6755
+ }
6756
+ return generateCode();
6757
+ });
6758
+ sv.file(schemaPath, (content) => {
6759
+ const { ast, generateCode } = parseScript(content);
6760
+ const createTable = (name) => _function.call(TABLE_TYPE[drizzleDialect], [name]);
6761
+ const userDecl = variables.declaration(ast, "const", "user", createTable("user"));
6762
+ const sessionDecl = variables.declaration(ast, "const", "session", createTable("session"));
6763
+ const user = exports$1.namedExport(ast, "user", userDecl);
6764
+ const session = exports$1.namedExport(ast, "session", sessionDecl);
6765
+ const userTable = getCallExpression(user);
6766
+ const sessionTable = getCallExpression(session);
6767
+ if (!userTable || !sessionTable) {
6768
+ throw new Error("failed to find call expression of `user` or `session`");
6769
+ }
6770
+ if (userTable.arguments.length === 1) {
6771
+ userTable.arguments.push(object$1.createEmpty());
6772
+ }
6773
+ if (sessionTable.arguments.length === 1) {
6774
+ sessionTable.arguments.push(object$1.createEmpty());
6775
+ }
6776
+ const userAttributes = userTable.arguments[1];
6777
+ const sessionAttributes = sessionTable.arguments[1];
6778
+ if (userAttributes?.type !== "ObjectExpression" || sessionAttributes?.type !== "ObjectExpression") {
6779
+ throw new Error("unexpected shape of `user` or `session` table definition");
6780
+ }
6781
+ if (drizzleDialect === "sqlite") {
6782
+ imports.addNamed(ast, "drizzle-orm/sqlite-core", {
6783
+ sqliteTable: "sqliteTable",
6784
+ text: "text",
6785
+ integer: "integer"
6786
+ });
6787
+ object$1.overrideProperties(userAttributes, {
6788
+ id: common.expressionFromString("text('id').primaryKey()")
6789
+ });
6790
+ if (options2.demo) {
6903
6791
  object$1.overrideProperties(userAttributes, {
6904
- id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()")
6905
- });
6906
- if (options2.demo) {
6907
- object$1.overrideProperties(userAttributes, {
6908
- username: common.expressionFromString(
6909
- "varchar('username', { length: 32 }).notNull().unique()"
6910
- ),
6911
- passwordHash: common.expressionFromString(
6912
- "varchar('password_hash', { length: 255 }).notNull()"
6913
- )
6914
- });
6915
- }
6916
- object$1.overrideProperties(sessionAttributes, {
6917
- id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"),
6918
- userId: common.expressionFromString(
6919
- "varchar('user_id', { length: 255 }).notNull().references(() => user.id)"
6920
- ),
6921
- expiresAt: common.expressionFromString("datetime('expires_at').notNull()")
6792
+ username: common.expressionFromString("text('username').notNull().unique()"),
6793
+ passwordHash: common.expressionFromString("text('password_hash').notNull()")
6922
6794
  });
6923
6795
  }
6924
- if (drizzleDialect === "postgresql") {
6925
- imports.addNamed(ast, "drizzle-orm/pg-core", {
6926
- pgTable: "pgTable",
6927
- text: "text",
6928
- timestamp: "timestamp"
6929
- });
6796
+ object$1.overrideProperties(sessionAttributes, {
6797
+ id: common.expressionFromString("text('id').primaryKey()"),
6798
+ userId: common.expressionFromString(
6799
+ "text('user_id').notNull().references(() => user.id)"
6800
+ ),
6801
+ expiresAt: common.expressionFromString(
6802
+ "integer('expires_at', { mode: 'timestamp' }).notNull()"
6803
+ )
6804
+ });
6805
+ }
6806
+ if (drizzleDialect === "mysql") {
6807
+ imports.addNamed(ast, "drizzle-orm/mysql-core", {
6808
+ mysqlTable: "mysqlTable",
6809
+ varchar: "varchar",
6810
+ datetime: "datetime"
6811
+ });
6812
+ object$1.overrideProperties(userAttributes, {
6813
+ id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()")
6814
+ });
6815
+ if (options2.demo) {
6930
6816
  object$1.overrideProperties(userAttributes, {
6931
- id: common.expressionFromString("text('id').primaryKey()")
6932
- });
6933
- if (options2.demo) {
6934
- object$1.overrideProperties(userAttributes, {
6935
- username: common.expressionFromString("text('username').notNull().unique()"),
6936
- passwordHash: common.expressionFromString("text('password_hash').notNull()")
6937
- });
6938
- }
6939
- object$1.overrideProperties(sessionAttributes, {
6940
- id: common.expressionFromString("text('id').primaryKey()"),
6941
- userId: common.expressionFromString(
6942
- "text('user_id').notNull().references(() => user.id)"
6817
+ username: common.expressionFromString(
6818
+ "varchar('username', { length: 32 }).notNull().unique()"
6943
6819
  ),
6944
- expiresAt: common.expressionFromString(
6945
- "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()"
6820
+ passwordHash: common.expressionFromString(
6821
+ "varchar('password_hash', { length: 255 }).notNull()"
6946
6822
  )
6947
6823
  });
6948
6824
  }
6949
- let code = generateCode();
6950
- if (typescript) {
6951
- if (!code.includes("export type Session =")) {
6952
- code += "\n\nexport type Session = typeof session.$inferSelect;";
6953
- }
6954
- if (!code.includes("export type User =")) {
6955
- code += "\n\nexport type User = typeof user.$inferSelect;";
6956
- }
6957
- }
6958
- return code;
6825
+ object$1.overrideProperties(sessionAttributes, {
6826
+ id: common.expressionFromString("varchar('id', { length: 255 }).primaryKey()"),
6827
+ userId: common.expressionFromString(
6828
+ "varchar('user_id', { length: 255 }).notNull().references(() => user.id)"
6829
+ ),
6830
+ expiresAt: common.expressionFromString("datetime('expires_at').notNull()")
6831
+ });
6959
6832
  }
6960
- },
6961
- {
6962
- name: ({ kit: kit2, typescript }) => `${kit2?.libDirectory}/server/auth.${typescript ? "ts" : "js"}`,
6963
- content: ({ content, typescript }) => {
6964
- const { ast, generateCode } = parseScript(content);
6965
- imports.addNamespace(ast, "$lib/server/db/schema", "table");
6966
- imports.addNamed(ast, "$lib/server/db", { db: "db" });
6967
- imports.addNamed(ast, "@oslojs/encoding", {
6968
- encodeBase32LowerCase: "encodeBase32LowerCase",
6969
- encodeHexLowerCase: "encodeHexLowerCase"
6833
+ if (drizzleDialect === "postgresql") {
6834
+ imports.addNamed(ast, "drizzle-orm/pg-core", {
6835
+ pgTable: "pgTable",
6836
+ text: "text",
6837
+ timestamp: "timestamp"
6970
6838
  });
6971
- imports.addNamed(ast, "@oslojs/crypto/sha2", { sha256: "sha256" });
6972
- imports.addNamed(ast, "drizzle-orm", { eq: "eq" });
6973
- if (typescript) {
6974
- imports.addNamed(ast, "@sveltejs/kit", { RequestEvent: "RequestEvent" }, true);
6839
+ object$1.overrideProperties(userAttributes, {
6840
+ id: common.expressionFromString("text('id').primaryKey()")
6841
+ });
6842
+ if (options2.demo) {
6843
+ object$1.overrideProperties(userAttributes, {
6844
+ username: common.expressionFromString("text('username').notNull().unique()"),
6845
+ passwordHash: common.expressionFromString("text('password_hash').notNull()")
6846
+ });
6975
6847
  }
6976
- const ms = new MagicString(generateCode().trim());
6977
- const [ts] = utils.createPrinter(typescript);
6978
- if (!ms.original.includes("const DAY_IN_MS")) {
6979
- ms.append("\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;");
6848
+ object$1.overrideProperties(sessionAttributes, {
6849
+ id: common.expressionFromString("text('id').primaryKey()"),
6850
+ userId: common.expressionFromString(
6851
+ "text('user_id').notNull().references(() => user.id)"
6852
+ ),
6853
+ expiresAt: common.expressionFromString(
6854
+ "timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()"
6855
+ )
6856
+ });
6857
+ }
6858
+ let code = generateCode();
6859
+ if (typescript) {
6860
+ if (!code.includes("export type Session =")) {
6861
+ code += "\n\nexport type Session = typeof session.$inferSelect;";
6980
6862
  }
6981
- if (!ms.original.includes("export const sessionCookieName")) {
6982
- ms.append("\n\nexport const sessionCookieName = 'auth-session';");
6863
+ if (!code.includes("export type User =")) {
6864
+ code += "\n\nexport type User = typeof user.$inferSelect;";
6983
6865
  }
6984
- if (!ms.original.includes("export function generateSessionToken")) {
6985
- const generateSessionToken = dedent`
6986
- export function generateSessionToken() {
6987
- const bytes = crypto.getRandomValues(new Uint8Array(20));
6988
- const token = encodeBase32LowerCase(bytes);
6989
- return token;
6990
- }`;
6991
- ms.append(`
6866
+ }
6867
+ return code;
6868
+ });
6869
+ sv.file(`${kit$1?.libDirectory}/server/auth.${ext}`, (content) => {
6870
+ const { ast, generateCode } = parseScript(content);
6871
+ imports.addNamespace(ast, "$lib/server/db/schema", "table");
6872
+ imports.addNamed(ast, "$lib/server/db", { db: "db" });
6873
+ imports.addNamed(ast, "@oslojs/encoding", {
6874
+ encodeBase64url: "encodeBase64url",
6875
+ encodeHexLowerCase: "encodeHexLowerCase"
6876
+ });
6877
+ imports.addNamed(ast, "@oslojs/crypto/sha2", { sha256: "sha256" });
6878
+ imports.addNamed(ast, "drizzle-orm", { eq: "eq" });
6879
+ if (typescript) {
6880
+ imports.addNamed(ast, "@sveltejs/kit", { RequestEvent: "RequestEvent" }, true);
6881
+ }
6882
+ const ms = new MagicString(generateCode().trim());
6883
+ const [ts] = utils.createPrinter(typescript);
6884
+ if (!ms.original.includes("const DAY_IN_MS")) {
6885
+ ms.append("\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;");
6886
+ }
6887
+ if (!ms.original.includes("export const sessionCookieName")) {
6888
+ ms.append("\n\nexport const sessionCookieName = 'auth-session';");
6889
+ }
6890
+ if (!ms.original.includes("export function generateSessionToken")) {
6891
+ const generateSessionToken = dedent`
6892
+ export function generateSessionToken() {
6893
+ const bytes = crypto.getRandomValues(new Uint8Array(18));
6894
+ const token = encodeBase64url(bytes);
6895
+ return token;
6896
+ }`;
6897
+ ms.append(`
6992
6898
 
6993
6899
  ${generateSessionToken}`);
6994
- }
6995
- if (!ms.original.includes("async function createSession")) {
6996
- const createSession = dedent`
6997
- ${ts("", "/**")}
6998
- ${ts("", " * @param {string} token")}
6999
- ${ts("", " * @param {string} userId")}
7000
- ${ts("", " */")}
7001
- export async function createSession(token${ts(": string")}, userId${ts(": string")}) {
7002
- const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
7003
- const session${ts(": table.Session")} = {
7004
- id: sessionId,
7005
- userId,
7006
- expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
7007
- };
7008
- await db.insert(table.session).values(session);
7009
- return session;
7010
- }`;
7011
- ms.append(`
6900
+ }
6901
+ if (!ms.original.includes("async function createSession")) {
6902
+ const createSession = dedent`
6903
+ ${ts("", "/**")}
6904
+ ${ts("", " * @param {string} token")}
6905
+ ${ts("", " * @param {string} userId")}
6906
+ ${ts("", " */")}
6907
+ export async function createSession(token${ts(": string")}, userId${ts(": string")}) {
6908
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
6909
+ const session${ts(": table.Session")} = {
6910
+ id: sessionId,
6911
+ userId,
6912
+ expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
6913
+ };
6914
+ await db.insert(table.session).values(session);
6915
+ return session;
6916
+ }`;
6917
+ ms.append(`
7012
6918
 
7013
6919
  ${createSession}`);
7014
- }
7015
- if (!ms.original.includes("async function validateSessionToken")) {
7016
- const validateSessionToken = dedent`
7017
- ${ts("", "/** @param {string} token */")}
7018
- export async function validateSessionToken(token${ts(": string")}) {
7019
- const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
7020
- const [result] = await db
7021
- .select({
7022
- // Adjust user table here to tweak returned data
7023
- user: { id: table.user.id, username: table.user.username },
7024
- session: table.session
7025
- })
7026
- .from(table.session)
7027
- .innerJoin(table.user, eq(table.session.userId, table.user.id))
7028
- .where(eq(table.session.id, sessionId));
7029
-
7030
- if (!result) {
7031
- return { session: null, user: null };
7032
- }
7033
- const { session, user } = result;
7034
-
7035
- const sessionExpired = Date.now() >= session.expiresAt.getTime();
7036
- if (sessionExpired) {
7037
- await db.delete(table.session).where(eq(table.session.id, session.id));
7038
- return { session: null, user: null };
7039
- }
7040
-
7041
- const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
7042
- if (renewSession) {
7043
- session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
7044
- await db
7045
- .update(table.session)
7046
- .set({ expiresAt: session.expiresAt })
7047
- .where(eq(table.session.id, session.id));
7048
- }
7049
-
7050
- return { session, user };
7051
- }`;
7052
- ms.append(`
6920
+ }
6921
+ if (!ms.original.includes("async function validateSessionToken")) {
6922
+ const validateSessionToken = dedent`
6923
+ ${ts("", "/** @param {string} token */")}
6924
+ export async function validateSessionToken(token${ts(": string")}) {
6925
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
6926
+ const [result] = await db
6927
+ .select({
6928
+ // Adjust user table here to tweak returned data
6929
+ user: { id: table.user.id, username: table.user.username },
6930
+ session: table.session
6931
+ })
6932
+ .from(table.session)
6933
+ .innerJoin(table.user, eq(table.session.userId, table.user.id))
6934
+ .where(eq(table.session.id, sessionId));
6935
+
6936
+ if (!result) {
6937
+ return { session: null, user: null };
6938
+ }
6939
+ const { session, user } = result;
6940
+
6941
+ const sessionExpired = Date.now() >= session.expiresAt.getTime();
6942
+ if (sessionExpired) {
6943
+ await db.delete(table.session).where(eq(table.session.id, session.id));
6944
+ return { session: null, user: null };
6945
+ }
6946
+
6947
+ const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
6948
+ if (renewSession) {
6949
+ session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
6950
+ await db
6951
+ .update(table.session)
6952
+ .set({ expiresAt: session.expiresAt })
6953
+ .where(eq(table.session.id, session.id));
6954
+ }
6955
+
6956
+ return { session, user };
6957
+ }`;
6958
+ ms.append(`
7053
6959
 
7054
6960
  ${validateSessionToken}`);
7055
- }
7056
- if (typescript && !ms.original.includes("export type SessionValidationResult")) {
7057
- const sessionType = "export type SessionValidationResult = Awaited<ReturnType<typeof validateSessionToken>>;";
7058
- ms.append(`
6961
+ }
6962
+ if (typescript && !ms.original.includes("export type SessionValidationResult")) {
6963
+ const sessionType = "export type SessionValidationResult = Awaited<ReturnType<typeof validateSessionToken>>;";
6964
+ ms.append(`
7059
6965
 
7060
6966
  ${sessionType}`);
7061
- }
7062
- if (!ms.original.includes("async function invalidateSession")) {
7063
- const invalidateSession = dedent`
7064
- ${ts("", "/** @param {string} sessionId */")}
7065
- export async function invalidateSession(sessionId${ts(": string")}) {
7066
- await db.delete(table.session).where(eq(table.session.id, sessionId));
7067
- }`;
7068
- ms.append(`
6967
+ }
6968
+ if (!ms.original.includes("async function invalidateSession")) {
6969
+ const invalidateSession = dedent`
6970
+ ${ts("", "/** @param {string} sessionId */")}
6971
+ export async function invalidateSession(sessionId${ts(": string")}) {
6972
+ await db.delete(table.session).where(eq(table.session.id, sessionId));
6973
+ }`;
6974
+ ms.append(`
7069
6975
 
7070
6976
  ${invalidateSession}`);
7071
- }
7072
- if (!ms.original.includes("export function setSessionTokenCookie")) {
7073
- const setSessionTokenCookie = dedent`
7074
- ${ts("", "/**")}
7075
- ${ts("", ' * @param {import("@sveltejs/kit").RequestEvent} event')}
7076
- ${ts("", " * @param {string} token")}
7077
- ${ts("", " * @param {Date} expiresAt")}
7078
- ${ts("", " */")}
7079
- export function setSessionTokenCookie(event${ts(": RequestEvent")}, token${ts(": string")}, expiresAt${ts(": Date")}) {
7080
- event.cookies.set(sessionCookieName, token, {
7081
- expires: expiresAt,
7082
- path: '/'
7083
- });
7084
- }`;
7085
- ms.append(`
6977
+ }
6978
+ if (!ms.original.includes("export function setSessionTokenCookie")) {
6979
+ const setSessionTokenCookie = dedent`
6980
+ ${ts("", "/**")}
6981
+ ${ts("", ' * @param {import("@sveltejs/kit").RequestEvent} event')}
6982
+ ${ts("", " * @param {string} token")}
6983
+ ${ts("", " * @param {Date} expiresAt")}
6984
+ ${ts("", " */")}
6985
+ export function setSessionTokenCookie(event${ts(": RequestEvent")}, token${ts(": string")}, expiresAt${ts(": Date")}) {
6986
+ event.cookies.set(sessionCookieName, token, {
6987
+ expires: expiresAt,
6988
+ path: '/'
6989
+ });
6990
+ }`;
6991
+ ms.append(`
7086
6992
 
7087
6993
  ${setSessionTokenCookie}`);
7088
- }
7089
- if (!ms.original.includes("export function deleteSessionTokenCookie")) {
7090
- const deleteSessionTokenCookie = dedent`
7091
- ${ts("", '/** @param {import("@sveltejs/kit").RequestEvent} event */')}
7092
- export function deleteSessionTokenCookie(event${ts(": RequestEvent")}) {
7093
- event.cookies.delete(sessionCookieName, {
7094
- path: '/'
7095
- });
7096
- }`;
7097
- ms.append(`
6994
+ }
6995
+ if (!ms.original.includes("export function deleteSessionTokenCookie")) {
6996
+ const deleteSessionTokenCookie = dedent`
6997
+ ${ts("", '/** @param {import("@sveltejs/kit").RequestEvent} event */')}
6998
+ export function deleteSessionTokenCookie(event${ts(": RequestEvent")}) {
6999
+ event.cookies.delete(sessionCookieName, {
7000
+ path: '/'
7001
+ });
7002
+ }`;
7003
+ ms.append(`
7098
7004
 
7099
7005
  ${deleteSessionTokenCookie}`);
7100
- }
7101
- return ms.toString();
7102
7006
  }
7103
- },
7104
- {
7105
- name: () => "src/app.d.ts",
7106
- condition: ({ typescript }) => typescript,
7107
- content: ({ content }) => {
7007
+ return ms.toString();
7008
+ });
7009
+ if (typescript) {
7010
+ sv.file("src/app.d.ts", (content) => {
7108
7011
  const { ast, generateCode } = parseScript(content);
7109
7012
  const locals = kit.addGlobalAppInterface(ast, "Locals");
7110
7013
  if (!locals) {
@@ -7119,30 +7022,21 @@ ${deleteSessionTokenCookie}`);
7119
7022
  locals.body.body.push(createLuciaType("session"));
7120
7023
  }
7121
7024
  return generateCode();
7122
- }
7123
- },
7124
- {
7125
- name: ({ typescript }) => `src/hooks.server.${typescript ? "ts" : "js"}`,
7126
- content: ({ content, typescript }) => {
7127
- const { ast, generateCode } = parseScript(content);
7128
- imports.addNamespace(ast, "$lib/server/auth.js", "auth");
7129
- kit.addHooksHandle(ast, typescript, "handleAuth", getAuthHandleContent());
7130
- return generateCode();
7131
- }
7132
- },
7133
- // DEMO
7134
- // login/register
7135
- {
7136
- name: ({ kit: kit2 }) => `${kit2?.routesDirectory}/demo/+page.svelte`,
7137
- condition: ({ options: options2 }) => options2.demo,
7138
- content: (editor) => addToDemoPage(editor, "lucia")
7139
- },
7140
- {
7141
- name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/lucia/login/+page.server.${typescript ? "ts" : "js"}`,
7142
- condition: ({ options: options2 }) => options2.demo,
7143
- content({ content, typescript, kit: kit2 }) {
7025
+ });
7026
+ }
7027
+ sv.file(`src/hooks.server.${ext}`, (content) => {
7028
+ const { ast, generateCode } = parseScript(content);
7029
+ imports.addNamespace(ast, "$lib/server/auth.js", "auth");
7030
+ kit.addHooksHandle(ast, typescript, "handleAuth", getAuthHandleContent());
7031
+ return generateCode();
7032
+ });
7033
+ if (options2.demo) {
7034
+ sv.file(`${kit$1?.routesDirectory}/demo/+page.svelte`, (content) => {
7035
+ return addToDemoPage(content, "lucia");
7036
+ });
7037
+ sv.file(`${kit$1.routesDirectory}/demo/lucia/login/+page.server.${ext}`, (content) => {
7144
7038
  if (content) {
7145
- const filePath = `${kit2.routesDirectory}/demo/lucia/login/+page.server.${typescript ? "ts" : "js"}`;
7039
+ const filePath = `${kit$1.routesDirectory}/demo/lucia/login/+page.server.${typescript ? "ts" : "js"}`;
7146
7040
  log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
7147
7041
  return content;
7148
7042
  }
@@ -7260,29 +7154,20 @@ ${deleteSessionTokenCookie}`);
7260
7154
  );
7261
7155
  }
7262
7156
  `;
7263
- }
7264
- },
7265
- {
7266
- name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/lucia/login/+page.svelte`,
7267
- condition: ({ options: options2 }) => options2.demo,
7268
- content({ content, dependencyVersion, typescript, kit: kit2 }) {
7157
+ });
7158
+ sv.file(`${kit$1.routesDirectory}/demo/lucia/login/+page.svelte`, (content) => {
7269
7159
  if (content) {
7270
- const filePath = `${kit2.routesDirectory}/demo/lucia/login/+page.svelte`;
7160
+ const filePath = `${kit$1.routesDirectory}/demo/lucia/login/+page.svelte`;
7271
7161
  log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
7272
7162
  return content;
7273
7163
  }
7274
7164
  const svelte5 = !!dependencyVersion("svelte")?.startsWith("5");
7275
7165
  const [ts, s5] = utils.createPrinter(typescript, svelte5);
7276
7166
  return dedent(_a || (_a = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n ", "\n <\/script>\n\n <h1>Login/Register</h1>\n <form method='post' action='?/login' use:enhance>\n <label>\n Username\n <input name='username' />\n </label>\n <label>\n Password\n <input type='password' name='password' />\n </label>\n <button>Login</button>\n <button formaction='?/register'>Register</button>\n </form>\n <p style='color: red'>{form?.message ?? ''}</p>\n "])), ts("lang='ts'"), ts("import type { ActionData } from './$types';\n"), s5(`let { form }${ts(": { form: ActionData }")} = $props();`, `export let form${ts(": ActionData")};`));
7277
- }
7278
- },
7279
- // logout
7280
- {
7281
- name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/lucia/+page.server.${typescript ? "ts" : "js"}`,
7282
- condition: ({ options: options2 }) => options2.demo,
7283
- content({ content, typescript, kit: kit2 }) {
7167
+ });
7168
+ sv.file(`${kit$1.routesDirectory}/demo/lucia/+page.server.${ext}`, (content) => {
7284
7169
  if (content) {
7285
- const filePath = `${kit2.routesDirectory}/demo/lucia/+page.server.${typescript ? "ts" : "js"}`;
7170
+ const filePath = `${kit$1.routesDirectory}/demo/lucia/+page.server.${typescript ? "ts" : "js"}`;
7286
7171
  log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
7287
7172
  return content;
7288
7173
  }
@@ -7310,23 +7195,19 @@ ${deleteSessionTokenCookie}`);
7310
7195
  },
7311
7196
  };
7312
7197
  `;
7313
- }
7314
- },
7315
- {
7316
- name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/lucia/+page.svelte`,
7317
- condition: ({ options: options2 }) => options2.demo,
7318
- content({ content, dependencyVersion, typescript, kit: kit2 }) {
7198
+ });
7199
+ sv.file(`${kit$1.routesDirectory}/demo/lucia/+page.svelte`, (content) => {
7319
7200
  if (content) {
7320
- const filePath = `${kit2.routesDirectory}/demo/lucia/+page.svelte`;
7201
+ const filePath = `${kit$1.routesDirectory}/demo/lucia/+page.svelte`;
7321
7202
  log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
7322
7203
  return content;
7323
7204
  }
7324
7205
  const svelte5 = !!dependencyVersion("svelte")?.startsWith("5");
7325
7206
  const [ts, s5] = utils.createPrinter(typescript, svelte5);
7326
7207
  return dedent(_b || (_b = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n ", "\n <\/script>\n\n <h1>Hi, {data.user.username}!</h1>\n <p>Your user ID is {data.user.id}.</p>\n <form method='post' action='?/logout' use:enhance>\n <button>Sign out</button>\n </form>\n "])), ts("lang='ts'"), ts("import type { PageServerData } from './$types';\n"), s5(`let { data }${ts(": { data: PageServerData }")} = $props();`, `export let data${ts(": PageServerData")};`));
7327
- }
7208
+ });
7328
7209
  }
7329
- ],
7210
+ },
7330
7211
  nextSteps: ({ highlighter, options: options2, packageManager }) => {
7331
7212
  const steps = [
7332
7213
  `Run ${highlighter.command(`${packageManager} run db:push`)} to update your database schema`
@@ -7400,36 +7281,32 @@ function getCallExpression(ast) {
7400
7281
  return callExpression;
7401
7282
  }
7402
7283
 
7403
- var mdsvex = defineAdder({
7284
+ var mdsvex = defineAddon({
7404
7285
  id: "mdsvex",
7405
- environments: { svelte: true, kit: true },
7406
7286
  homepage: "https://mdsvex.pngwn.io",
7407
7287
  options: {},
7408
- packages: [{ name: "mdsvex", version: "^0.11.2", dev: true }],
7409
- files: [
7410
- {
7411
- name: () => "svelte.config.js",
7412
- content: ({ content }) => {
7413
- const { ast, generateCode } = parseScript(content);
7414
- imports.addNamed(ast, "mdsvex", { mdsvex: "mdsvex" });
7415
- const { value: exportDefault } = exports$1.defaultExport(ast, object$1.createEmpty());
7416
- let preprocessorArray = object$1.property(exportDefault, "preprocess", array$1.createEmpty());
7417
- const isArray = preprocessorArray.type === "ArrayExpression";
7418
- if (!isArray) {
7419
- const previousElement = preprocessorArray;
7420
- preprocessorArray = array$1.createEmpty();
7421
- array$1.push(preprocessorArray, previousElement);
7422
- object$1.overrideProperty(exportDefault, "preprocess", preprocessorArray);
7423
- }
7424
- const mdsvexCall = _function.call("mdsvex", []);
7425
- array$1.push(preprocessorArray, mdsvexCall);
7426
- const extensionsArray = object$1.property(exportDefault, "extensions", array$1.createEmpty());
7427
- array$1.push(extensionsArray, ".svelte");
7428
- array$1.push(extensionsArray, ".svx");
7429
- return generateCode();
7430
- }
7431
- }
7432
- ]
7288
+ run: ({ sv }) => {
7289
+ sv.devDependency("mdsvex", "^0.11.2");
7290
+ sv.file("svelte.config.js", (content) => {
7291
+ const { ast, generateCode } = parseScript(content);
7292
+ imports.addNamed(ast, "mdsvex", { mdsvex: "mdsvex" });
7293
+ const { value: exportDefault } = exports$1.defaultExport(ast, object$1.createEmpty());
7294
+ let preprocessorArray = object$1.property(exportDefault, "preprocess", array$1.createEmpty());
7295
+ const isArray = preprocessorArray.type === "ArrayExpression";
7296
+ if (!isArray) {
7297
+ const previousElement = preprocessorArray;
7298
+ preprocessorArray = array$1.createEmpty();
7299
+ array$1.push(preprocessorArray, previousElement);
7300
+ object$1.overrideProperty(exportDefault, "preprocess", preprocessorArray);
7301
+ }
7302
+ const mdsvexCall = _function.call("mdsvex", []);
7303
+ array$1.push(preprocessorArray, mdsvexCall);
7304
+ const extensionsArray = object$1.property(exportDefault, "extensions", array$1.createEmpty());
7305
+ array$1.push(extensionsArray, ".svelte");
7306
+ array$1.push(extensionsArray, ".svx");
7307
+ return generateCode();
7308
+ });
7309
+ }
7433
7310
  });
7434
7311
 
7435
7312
  function element(tagName, attributes = {}) {
@@ -7472,7 +7349,7 @@ const DEFAULT_INLANG_PROJECT = {
7472
7349
  pathPattern: "./messages/{languageTag}.json"
7473
7350
  }
7474
7351
  };
7475
- const options$2 = defineAdderOptions({
7352
+ const options$2 = defineAddonOptions({
7476
7353
  availableLanguageTags: {
7477
7354
  question: `Which languages would you like to support? ${picocolors.gray("(e.g. en,de-ch)")}`,
7478
7355
  type: "string",
@@ -7498,162 +7375,118 @@ const options$2 = defineAdderOptions({
7498
7375
  question: "Do you want to include a demo?"
7499
7376
  }
7500
7377
  });
7501
- var paraglide = defineAdder({
7378
+ var paraglide = defineAddon({
7502
7379
  id: "paraglide",
7503
- environments: { svelte: false, kit: true },
7504
7380
  homepage: "https://inlang.com",
7505
7381
  options: options$2,
7506
- packages: [
7507
- {
7508
- name: "@inlang/paraglide-sveltekit",
7509
- version: "^0.11.1",
7510
- dev: false
7511
- }
7512
- ],
7513
- files: [
7514
- {
7515
- // create an inlang project if it doesn't exist yet
7516
- name: () => "project.inlang/settings.json",
7517
- condition: ({ cwd }) => !fs$3.existsSync(path$2.join(cwd, "project.inlang/settings.json")),
7518
- content: ({ options: options2, content }) => {
7519
- const { data, generateCode } = parseJson(content);
7520
- for (const key in DEFAULT_INLANG_PROJECT) {
7521
- data[key] = DEFAULT_INLANG_PROJECT[key];
7522
- }
7523
- const { validLanguageTags } = parseLanguageTagInput(options2.availableLanguageTags);
7524
- const sourceLanguageTag = validLanguageTags[0];
7525
- data.sourceLanguageTag = sourceLanguageTag;
7526
- data.languageTags = validLanguageTags;
7527
- return generateCode();
7528
- }
7529
- },
7530
- {
7531
- // add the vite plugin
7532
- name: ({ typescript }) => `vite.config.${typescript ? "ts" : "js"}`,
7533
- content: ({ content }) => {
7534
- const { ast, generateCode } = parseScript(content);
7535
- const vitePluginName = "paraglide";
7536
- imports.addNamed(ast, "@inlang/paraglide-sveltekit/vite", { paraglide: vitePluginName });
7537
- const { value: rootObject } = exports$1.defaultExport(
7538
- ast,
7539
- _function.call("defineConfig", [])
7540
- );
7541
- const param1 = _function.argumentByIndex(rootObject, 0, object$1.createEmpty());
7542
- const pluginsArray = object$1.property(param1, "plugins", array$1.createEmpty());
7543
- const pluginFunctionCall = _function.call(vitePluginName, []);
7544
- const pluginConfig = object$1.create({
7545
- project: common.createLiteral("./project.inlang"),
7546
- outdir: common.createLiteral("./src/lib/paraglide")
7547
- });
7548
- _function.argumentByIndex(pluginFunctionCall, 0, pluginConfig);
7549
- array$1.push(pluginsArray, pluginFunctionCall);
7550
- return generateCode();
7551
- }
7552
- },
7553
- {
7554
- // src/lib/i18n file
7555
- name: ({ typescript }) => `src/lib/i18n.${typescript ? "ts" : "js"}`,
7556
- content({ content }) {
7557
- const { ast, generateCode } = parseScript(content);
7558
- imports.addNamed(ast, "@inlang/paraglide-sveltekit", { createI18n: "createI18n" });
7559
- imports.addDefault(ast, "$lib/paraglide/runtime", "* as runtime");
7560
- const createI18nExpression = common.expressionFromString("createI18n(runtime)");
7561
- const i18n = variables.declaration(ast, "const", "i18n", createI18nExpression);
7562
- const existingExport = exports$1.namedExport(ast, "i18n", i18n);
7563
- if (existingExport.declaration != i18n) {
7564
- log.warn("Setting up $lib/i18n failed because it already exports an i18n function");
7565
- }
7566
- return generateCode();
7567
- }
7568
- },
7569
- {
7570
- // reroute hook
7571
- name: ({ typescript }) => `src/hooks.${typescript ? "ts" : "js"}`,
7572
- content({ content }) {
7573
- const { ast, generateCode } = parseScript(content);
7574
- imports.addNamed(ast, "$lib/i18n", {
7575
- i18n: "i18n"
7576
- });
7577
- const expression = common.expressionFromString("i18n.reroute()");
7578
- const rerouteIdentifier = variables.declaration(ast, "const", "reroute", expression);
7579
- const existingExport = exports$1.namedExport(ast, "reroute", rerouteIdentifier);
7580
- if (existingExport.declaration != rerouteIdentifier) {
7581
- log.warn("Adding the reroute hook automatically failed. Add it manually");
7582
- }
7583
- return generateCode();
7584
- }
7585
- },
7586
- {
7587
- // handle hook
7588
- name: ({ typescript }) => `src/hooks.server.${typescript ? "ts" : "js"}`,
7589
- content({ content, typescript }) {
7590
- const { ast, generateCode } = parseScript(content);
7591
- imports.addNamed(ast, "$lib/i18n", {
7592
- i18n: "i18n"
7593
- });
7594
- const hookHandleContent = "i18n.handle()";
7595
- kit.addHooksHandle(ast, typescript, "handleParaglide", hookHandleContent);
7596
- return generateCode();
7597
- }
7598
- },
7599
- {
7600
- // add the <ParaglideJS> component to the layout
7601
- name: ({ kit: kit2 }) => `${kit2?.routesDirectory}/+layout.svelte`,
7602
- content: ({ content, dependencyVersion, typescript }) => {
7603
- const { script, template, generateCode } = parseSvelte(content, { typescript });
7604
- const paraglideComponentName = "ParaglideJS";
7605
- imports.addNamed(script.ast, "@inlang/paraglide-sveltekit", {
7606
- [paraglideComponentName]: paraglideComponentName
7607
- });
7608
- imports.addNamed(script.ast, "$lib/i18n", {
7609
- i18n: "i18n"
7610
- });
7611
- if (template.source.length === 0) {
7612
- const svelteVersion = dependencyVersion("svelte");
7613
- if (!svelteVersion) throw new Error("Failed to determine svelte version");
7614
- addSlot(script.ast, template.ast, svelteVersion);
7615
- }
7616
- const templateCode = new MagicString(template.generateCode());
7617
- if (!templateCode.original.includes("<ParaglideJS")) {
7618
- templateCode.indent();
7619
- templateCode.prepend("<ParaglideJS {i18n}>\n");
7620
- templateCode.append("\n</ParaglideJS>");
7621
- }
7622
- return generateCode({ script: script.generateCode(), template: templateCode.toString() });
7623
- }
7624
- },
7625
- {
7626
- // add the text-direction and lang attribute placeholders to app.html
7627
- name: () => "src/app.html",
7628
- content: ({ content }) => {
7629
- const { ast, generateCode } = parseHtml$1(content);
7630
- const htmlNode = ast.children.find(
7631
- (child) => child.type === index.Tag && child.name === "html"
7382
+ setup: ({ kit, unsupported }) => {
7383
+ if (!kit) unsupported("Requires SvelteKit");
7384
+ },
7385
+ run: ({ sv, options: options2, typescript, kit: kit$1, dependencyVersion }) => {
7386
+ const ext = typescript ? "ts" : "js";
7387
+ if (!kit$1) throw new Error("SvelteKit is required");
7388
+ sv.dependency("@inlang/paraglide-sveltekit", "^0.11.1");
7389
+ sv.file("project.inlang/settings.json", (content) => {
7390
+ if (content) return content;
7391
+ const { data, generateCode } = parseJson(content);
7392
+ for (const key in DEFAULT_INLANG_PROJECT) {
7393
+ data[key] = DEFAULT_INLANG_PROJECT[key];
7394
+ }
7395
+ const { validLanguageTags: validLanguageTags2 } = parseLanguageTagInput(options2.availableLanguageTags);
7396
+ const sourceLanguageTag = validLanguageTags2[0];
7397
+ data.sourceLanguageTag = sourceLanguageTag;
7398
+ data.languageTags = validLanguageTags2;
7399
+ return generateCode();
7400
+ });
7401
+ sv.file(`vite.config.${ext}`, (content) => {
7402
+ const { ast, generateCode } = parseScript(content);
7403
+ const vitePluginName = "paraglide";
7404
+ imports.addNamed(ast, "@inlang/paraglide-sveltekit/vite", { paraglide: vitePluginName });
7405
+ const { value: rootObject } = exports$1.defaultExport(ast, _function.call("defineConfig", []));
7406
+ const param1 = _function.argumentByIndex(rootObject, 0, object$1.createEmpty());
7407
+ const pluginsArray = object$1.property(param1, "plugins", array$1.createEmpty());
7408
+ const pluginFunctionCall = _function.call(vitePluginName, []);
7409
+ const pluginConfig = object$1.create({
7410
+ project: common.createLiteral("./project.inlang"),
7411
+ outdir: common.createLiteral("./src/lib/paraglide")
7412
+ });
7413
+ _function.argumentByIndex(pluginFunctionCall, 0, pluginConfig);
7414
+ array$1.push(pluginsArray, pluginFunctionCall);
7415
+ return generateCode();
7416
+ });
7417
+ sv.file(`src/lib/i18n.${ext}`, (content) => {
7418
+ const { ast, generateCode } = parseScript(content);
7419
+ imports.addNamed(ast, "@inlang/paraglide-sveltekit", { createI18n: "createI18n" });
7420
+ imports.addDefault(ast, "$lib/paraglide/runtime", "* as runtime");
7421
+ const createI18nExpression = common.expressionFromString("createI18n(runtime)");
7422
+ const i18n = variables.declaration(ast, "const", "i18n", createI18nExpression);
7423
+ const existingExport = exports$1.namedExport(ast, "i18n", i18n);
7424
+ if (existingExport.declaration !== i18n) {
7425
+ log.warn("Setting up $lib/i18n failed because it already exports an i18n function");
7426
+ }
7427
+ return generateCode();
7428
+ });
7429
+ sv.file(`src/hooks.${ext}`, (content) => {
7430
+ const { ast, generateCode } = parseScript(content);
7431
+ imports.addNamed(ast, "$lib/i18n", { i18n: "i18n" });
7432
+ const expression = common.expressionFromString("i18n.reroute()");
7433
+ const rerouteIdentifier = variables.declaration(ast, "const", "reroute", expression);
7434
+ const existingExport = exports$1.namedExport(ast, "reroute", rerouteIdentifier);
7435
+ if (existingExport.declaration !== rerouteIdentifier) {
7436
+ log.warn("Adding the reroute hook automatically failed. Add it manually");
7437
+ }
7438
+ return generateCode();
7439
+ });
7440
+ sv.file(`src/hooks.server.${ext}`, (content) => {
7441
+ const { ast, generateCode } = parseScript(content);
7442
+ imports.addNamed(ast, "$lib/i18n", { i18n: "i18n" });
7443
+ const hookHandleContent = "i18n.handle()";
7444
+ kit.addHooksHandle(ast, typescript, "handleParaglide", hookHandleContent);
7445
+ return generateCode();
7446
+ });
7447
+ sv.file(`${kit$1.routesDirectory}/+layout.svelte`, (content) => {
7448
+ const { script, template, generateCode } = parseSvelte(content, { typescript });
7449
+ const paraglideComponentName = "ParaglideJS";
7450
+ imports.addNamed(script.ast, "@inlang/paraglide-sveltekit", {
7451
+ [paraglideComponentName]: paraglideComponentName
7452
+ });
7453
+ imports.addNamed(script.ast, "$lib/i18n", { i18n: "i18n" });
7454
+ if (template.source.length === 0) {
7455
+ const svelteVersion = dependencyVersion("svelte");
7456
+ if (!svelteVersion) throw new Error("Failed to determine svelte version");
7457
+ addSlot(script.ast, template.ast, svelteVersion);
7458
+ }
7459
+ const templateCode = new MagicString(template.generateCode());
7460
+ if (!templateCode.original.includes("<ParaglideJS")) {
7461
+ templateCode.indent();
7462
+ templateCode.prepend("<ParaglideJS {i18n}>\n");
7463
+ templateCode.append("\n</ParaglideJS>");
7464
+ }
7465
+ return generateCode({ script: script.generateCode(), template: templateCode.toString() });
7466
+ });
7467
+ sv.file("src/app.html", (content) => {
7468
+ const { ast, generateCode } = parseHtml$1(content);
7469
+ const htmlNode = ast.children.find(
7470
+ (child) => child.type === index.Tag && child.name === "html"
7471
+ );
7472
+ if (!htmlNode) {
7473
+ log.warn(
7474
+ "Could not find <html> node in app.html. You'll need to add the language placeholder manually"
7632
7475
  );
7633
- if (!htmlNode) {
7634
- log.warn(
7635
- "Could not find <html> node in app.html. You'll need to add the language placeholder manually"
7636
- );
7637
- return generateCode();
7638
- }
7639
- htmlNode.attribs = {
7640
- ...htmlNode.attribs,
7641
- lang: "%paraglide.lang%",
7642
- dir: "%paraglide.textDirection%"
7643
- };
7644
7476
  return generateCode();
7645
7477
  }
7646
- },
7647
- {
7648
- name: ({ kit: kit2 }) => `${kit2?.routesDirectory}/demo/+page.svelte`,
7649
- condition: ({ options: options2 }) => options2.demo,
7650
- content: (editor) => addToDemoPage(editor, "paraglide")
7651
- },
7652
- {
7653
- // add usage example
7654
- name: ({ kit: kit2 }) => `${kit2?.routesDirectory}/demo/paraglide/+page.svelte`,
7655
- condition: ({ options: options2 }) => options2.demo,
7656
- content({ content, options: options2, typescript }) {
7478
+ htmlNode.attribs = {
7479
+ ...htmlNode.attribs,
7480
+ lang: "%paraglide.lang%",
7481
+ dir: "%paraglide.textDirection%"
7482
+ };
7483
+ return generateCode();
7484
+ });
7485
+ if (options2.demo) {
7486
+ sv.file(`${kit$1.routesDirectory}/demo/+page.svelte`, (content) => {
7487
+ return addToDemoPage(content, "paraglide");
7488
+ });
7489
+ sv.file(`${kit$1.routesDirectory}/demo/paraglide/+page.svelte`, (content) => {
7657
7490
  const { script, template, generateCode } = parseSvelte(content, { typescript });
7658
7491
  imports.addDefault(script.ast, "$lib/paraglide/messages.js", "* as m");
7659
7492
  imports.addNamed(script.ast, "$app/navigation", { goto: "goto" });
@@ -7673,41 +7506,36 @@ var paraglide = defineAdder({
7673
7506
  scriptCode.trim();
7674
7507
  scriptCode.append("\n\n");
7675
7508
  scriptCode.append(dedent`
7676
- ${ts("", "/**")}
7677
- ${ts("", '* @param import("$lib/paraglide/runtime").AvailableLanguageTag newLanguage')}
7678
- ${ts("", "*/")}
7679
- function switchToLanguage(newLanguage${ts(": AvailableLanguageTag")}) {
7680
- const canonicalPath = i18n.route($page.url.pathname);
7681
- const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
7682
- goto(localisedPath);
7683
- }
7684
- `);
7509
+ ${ts("", "/**")}
7510
+ ${ts("", '* @param import("$lib/paraglide/runtime").AvailableLanguageTag newLanguage')}
7511
+ ${ts("", "*/")}
7512
+ function switchToLanguage(newLanguage${ts(": AvailableLanguageTag")}) {
7513
+ const canonicalPath = i18n.route($page.url.pathname);
7514
+ const localisedPath = i18n.resolveRoute(canonicalPath, newLanguage);
7515
+ goto(localisedPath);
7516
+ }
7517
+ `);
7685
7518
  }
7686
7519
  const templateCode = new MagicString(template.source);
7687
7520
  templateCode.append("\n\n<h1>{m.hello_world({ name: 'SvelteKit User' })}</h1>\n");
7688
- const { validLanguageTags } = parseLanguageTagInput(options2.availableLanguageTags);
7689
- const links = validLanguageTags.map(
7521
+ const { validLanguageTags: validLanguageTags2 } = parseLanguageTagInput(options2.availableLanguageTags);
7522
+ const links = validLanguageTags2.map(
7690
7523
  (x) => `${templateCode.getIndentString()}<button onclick={() => switchToLanguage('${x}')}>${x}</button>`
7691
7524
  ).join("\n");
7692
7525
  templateCode.append(`<div>
7693
7526
  ${links}
7694
7527
  </div>`);
7695
7528
  return generateCode({ script: scriptCode.toString(), template: templateCode.toString() });
7696
- }
7529
+ });
7697
7530
  }
7698
- ],
7699
- postInstall: ({ cwd, options: options2 }) => {
7700
- const jsonData = {};
7701
- jsonData["$schema"] = "https://inlang.com/schema/inlang-message-format";
7702
7531
  const { validLanguageTags } = parseLanguageTagInput(options2.availableLanguageTags);
7703
7532
  for (const languageTag of validLanguageTags) {
7704
- jsonData.hello_world = `Hello, {name} from ${languageTag}!`;
7705
- const filePath = `messages/${languageTag}.json`;
7706
- const directoryPath = path$2.dirname(filePath);
7707
- const fullDirectoryPath = path$2.join(cwd, directoryPath);
7708
- const fullFilePath = path$2.join(cwd, filePath);
7709
- fs$3.mkdirSync(fullDirectoryPath, { recursive: true });
7710
- fs$3.writeFileSync(fullFilePath, JSON.stringify(jsonData, null, 2) + "\n");
7533
+ sv.file(`messages/${languageTag}.json`, (content) => {
7534
+ const { data, generateCode } = parseJson(content);
7535
+ data["$schema"] = "https://inlang.com/schema/inlang-message-format";
7536
+ data.hello_world = `Hello, {name} from ${languageTag}!`;
7537
+ return generateCode();
7538
+ });
7711
7539
  }
7712
7540
  },
7713
7541
  nextSteps: ({ highlighter }) => {
@@ -7741,181 +7569,142 @@ function parseLanguageTagInput(input) {
7741
7569
  };
7742
7570
  }
7743
7571
 
7744
- var playwright = defineAdder({
7572
+ var playwright = defineAddon({
7745
7573
  id: "playwright",
7746
- environments: { svelte: true, kit: true },
7747
7574
  homepage: "https://playwright.dev",
7748
7575
  options: {},
7749
- packages: [{ name: "@playwright/test", version: "^1.45.3", dev: true }],
7750
- files: [
7751
- {
7752
- name: () => "package.json",
7753
- content: ({ content }) => {
7754
- const { data, generateCode } = parseJson(content);
7755
- data.scripts ?? (data.scripts = {});
7756
- const scripts = data.scripts;
7757
- const TEST_CMD = "playwright test";
7758
- const RUN_TEST = "npm run test:e2e";
7759
- scripts["test:e2e"] ?? (scripts["test:e2e"] = TEST_CMD);
7760
- scripts["test"] ?? (scripts["test"] = RUN_TEST);
7761
- if (!scripts["test"].includes(RUN_TEST)) scripts["test"] += ` && ${RUN_TEST}`;
7762
- return generateCode();
7763
- }
7764
- },
7765
- {
7766
- name: () => ".gitignore",
7767
- condition: ({ cwd }) => fs$3.existsSync(join(cwd, ".gitignore")),
7768
- content: ({ content }) => {
7769
- if (content.includes("test-results")) return content;
7770
- return "test-results\n" + content.trim();
7771
- }
7772
- },
7773
- {
7774
- name: ({ typescript }) => `e2e/demo.test.${typescript ? "ts" : "js"}`,
7775
- content: ({ content }) => {
7776
- if (content) return content;
7777
- return dedent`
7778
- import { expect, test } from '@playwright/test';
7779
-
7780
- test('home page has expected h1', async ({ page }) => {
7781
- await page.goto('/');
7782
- await expect(page.locator('h1')).toBeVisible();
7783
- });
7784
- `;
7785
- }
7786
- },
7787
- {
7788
- name: ({ typescript }) => `playwright.config.${typescript ? "ts" : "js"}`,
7789
- content: ({ content }) => {
7790
- const { ast, generateCode } = parseScript(content);
7791
- const defineConfig = common.expressionFromString("defineConfig({})");
7792
- const defaultExport = exports$1.defaultExport(ast, defineConfig);
7793
- const config = {
7794
- webServer: object$1.create({
7795
- command: common.createLiteral("npm run build && npm run preview"),
7796
- port: common.expressionFromString("4173")
7797
- }),
7798
- testDir: common.createLiteral("e2e")
7799
- };
7800
- if (defaultExport.value.type === "CallExpression" && defaultExport.value.arguments[0]?.type === "ObjectExpression") {
7801
- imports.addNamed(ast, "@playwright/test", { defineConfig: "defineConfig" });
7802
- object$1.properties(defaultExport.value.arguments[0], config);
7803
- } else if (defaultExport.value.type === "ObjectExpression") {
7804
- object$1.properties(defaultExport.value, config);
7805
- } else {
7806
- log.warn("Unexpected playwright config for playwright adder. Could not update.");
7807
- }
7808
- return generateCode();
7576
+ run: ({ sv, typescript }) => {
7577
+ const ext = typescript ? "ts" : "js";
7578
+ sv.devDependency("@playwright/test", "^1.45.3");
7579
+ sv.file("package.json", (content) => {
7580
+ const { data, generateCode } = parseJson(content);
7581
+ data.scripts ?? (data.scripts = {});
7582
+ const scripts = data.scripts;
7583
+ const TEST_CMD = "playwright test";
7584
+ const RUN_TEST = "npm run test:e2e";
7585
+ scripts["test:e2e"] ?? (scripts["test:e2e"] = TEST_CMD);
7586
+ scripts["test"] ?? (scripts["test"] = RUN_TEST);
7587
+ if (!scripts["test"].includes(RUN_TEST)) scripts["test"] += ` && ${RUN_TEST}`;
7588
+ return generateCode();
7589
+ });
7590
+ sv.file(".gitignore", (content) => {
7591
+ if (!content) return content;
7592
+ if (content.includes("test-results")) return content;
7593
+ return "test-results\n" + content.trim();
7594
+ });
7595
+ sv.file(`e2e/demo.test.${ext}`, (content) => {
7596
+ if (content) return content;
7597
+ return dedent`
7598
+ import { expect, test } from '@playwright/test';
7599
+
7600
+ test('home page has expected h1', async ({ page }) => {
7601
+ await page.goto('/');
7602
+ await expect(page.locator('h1')).toBeVisible();
7603
+ });
7604
+ `;
7605
+ });
7606
+ sv.file(`playwright.config.${ext}`, (content) => {
7607
+ const { ast, generateCode } = parseScript(content);
7608
+ const defineConfig = common.expressionFromString("defineConfig({})");
7609
+ const defaultExport = exports$1.defaultExport(ast, defineConfig);
7610
+ const config = {
7611
+ webServer: object$1.create({
7612
+ command: common.createLiteral("npm run build && npm run preview"),
7613
+ port: common.expressionFromString("4173")
7614
+ }),
7615
+ testDir: common.createLiteral("e2e")
7616
+ };
7617
+ if (defaultExport.value.type === "CallExpression" && defaultExport.value.arguments[0]?.type === "ObjectExpression") {
7618
+ imports.addNamed(ast, "@playwright/test", { defineConfig: "defineConfig" });
7619
+ object$1.properties(defaultExport.value.arguments[0], config);
7620
+ } else if (defaultExport.value.type === "ObjectExpression") {
7621
+ object$1.properties(defaultExport.value, config);
7622
+ } else {
7623
+ log.warn("Unexpected playwright config for playwright add-on. Could not update.");
7809
7624
  }
7810
- }
7811
- ]
7625
+ return generateCode();
7626
+ });
7627
+ }
7812
7628
  });
7813
7629
 
7814
- var prettier = defineAdder({
7630
+ var prettier = defineAddon({
7815
7631
  id: "prettier",
7816
- environments: { svelte: true, kit: true },
7817
7632
  homepage: "https://prettier.io",
7818
7633
  options: {},
7819
- packages: [
7820
- { name: "prettier", version: "^3.3.2", dev: true },
7821
- { name: "prettier-plugin-svelte", version: "^3.2.6", dev: true },
7822
- {
7823
- name: "eslint-config-prettier",
7824
- version: "^9.1.0",
7825
- dev: true,
7826
- condition: ({ dependencyVersion }) => hasEslint(dependencyVersion)
7827
- }
7828
- ],
7829
- files: [
7830
- {
7831
- name: () => ".prettierignore",
7832
- content: ({ content }) => {
7833
- if (content) return content;
7834
- return dedent`
7835
- # Package Managers
7836
- package-lock.json
7837
- pnpm-lock.yaml
7838
- yarn.lock
7839
- `;
7840
- }
7841
- },
7842
- {
7843
- name: () => ".prettierrc",
7844
- content: ({ content }) => {
7845
- const { data, generateCode } = parseJson(content);
7846
- if (Object.keys(data).length === 0) {
7847
- data.useTabs = true;
7848
- data.singleQuote = true;
7849
- data.trailingComma = "none";
7850
- data.printWidth = 100;
7851
- }
7852
- data.plugins ?? (data.plugins = []);
7853
- data.overrides ?? (data.overrides = []);
7854
- const plugins = data.plugins;
7855
- if (!plugins.includes("prettier-plugin-svelte")) {
7856
- data.plugins.unshift("prettier-plugin-svelte");
7857
- }
7858
- const overrides = data.overrides;
7859
- const override = overrides.find((o) => o?.options?.parser === "svelte");
7860
- if (!override) {
7861
- overrides.push({ files: "*.svelte", options: { parser: "svelte" } });
7862
- }
7863
- return generateCode();
7864
- }
7865
- },
7866
- {
7867
- name: () => "package.json",
7868
- content: ({ content, dependencyVersion }) => {
7869
- const { data, generateCode } = parseJson(content);
7870
- data.scripts ?? (data.scripts = {});
7871
- const scripts = data.scripts;
7872
- const CHECK_CMD = "prettier --check .";
7873
- scripts["format"] ?? (scripts["format"] = "prettier --write .");
7874
- if (hasEslint(dependencyVersion)) {
7875
- scripts["lint"] ?? (scripts["lint"] = `${CHECK_CMD} && eslint .`);
7876
- if (!scripts["lint"].includes(CHECK_CMD)) scripts["lint"] += ` && ${CHECK_CMD}`;
7877
- } else {
7878
- scripts["lint"] ?? (scripts["lint"] = CHECK_CMD);
7879
- }
7880
- return generateCode();
7634
+ run: ({ sv, dependencyVersion }) => {
7635
+ sv.devDependency("prettier", "^3.3.2");
7636
+ sv.devDependency("prettier-plugin-svelte", "^3.2.6");
7637
+ sv.file(".prettierignore", (content) => {
7638
+ if (content) return content;
7639
+ return dedent`
7640
+ # Package Managers
7641
+ package-lock.json
7642
+ pnpm-lock.yaml
7643
+ yarn.lock
7644
+ `;
7645
+ });
7646
+ sv.file(".prettierrc", (content) => {
7647
+ const { data, generateCode } = parseJson(content);
7648
+ if (Object.keys(data).length === 0) {
7649
+ data.useTabs = true;
7650
+ data.singleQuote = true;
7651
+ data.trailingComma = "none";
7652
+ data.printWidth = 100;
7653
+ }
7654
+ data.plugins ?? (data.plugins = []);
7655
+ data.overrides ?? (data.overrides = []);
7656
+ const plugins = data.plugins;
7657
+ if (!plugins.includes("prettier-plugin-svelte")) {
7658
+ data.plugins.unshift("prettier-plugin-svelte");
7659
+ }
7660
+ const overrides = data.overrides;
7661
+ const override = overrides.find((o) => o?.options?.parser === "svelte");
7662
+ if (!override) {
7663
+ overrides.push({ files: "*.svelte", options: { parser: "svelte" } });
7664
+ }
7665
+ return generateCode();
7666
+ });
7667
+ const eslintVersion = dependencyVersion("eslint");
7668
+ const eslintInstalled = hasEslint(eslintVersion);
7669
+ sv.file("package.json", (content) => {
7670
+ const { data, generateCode } = parseJson(content);
7671
+ data.scripts ?? (data.scripts = {});
7672
+ const scripts = data.scripts;
7673
+ const CHECK_CMD = "prettier --check .";
7674
+ scripts["format"] ?? (scripts["format"] = "prettier --write .");
7675
+ if (eslintInstalled) {
7676
+ scripts["lint"] ?? (scripts["lint"] = `${CHECK_CMD} && eslint .`);
7677
+ if (!scripts["lint"].includes(CHECK_CMD)) scripts["lint"] += ` && ${CHECK_CMD}`;
7678
+ } else {
7679
+ scripts["lint"] ?? (scripts["lint"] = CHECK_CMD);
7881
7680
  }
7882
- },
7883
- {
7884
- name: () => "eslint.config.js",
7885
- condition: ({ dependencyVersion }) => {
7886
- if (dependencyVersion("eslint")?.startsWith(SUPPORTED_ESLINT_VERSION) === false) {
7887
- log.warn(
7888
- `An older major version of ${picocolors.yellow(
7889
- "eslint"
7890
- )} was detected. Skipping ${picocolors.yellow("eslint-config-prettier")} installation.`
7891
- );
7892
- }
7893
- return hasEslint(dependencyVersion);
7894
- },
7895
- content: addEslintConfigPrettier
7681
+ return generateCode();
7682
+ });
7683
+ if (eslintVersion?.startsWith(SUPPORTED_ESLINT_VERSION) === false) {
7684
+ log.warn(
7685
+ `An older major version of ${picocolors.yellow(
7686
+ "eslint"
7687
+ )} was detected. Skipping ${picocolors.yellow("eslint-config-prettier")} installation.`
7688
+ );
7896
7689
  }
7897
- ]
7690
+ if (eslintInstalled) {
7691
+ sv.devDependency("eslint-config-prettier", "^9.1.0");
7692
+ sv.file("eslint.config.js", addEslintConfigPrettier);
7693
+ }
7694
+ }
7898
7695
  });
7899
7696
  const SUPPORTED_ESLINT_VERSION = "9";
7900
- function hasEslint(dependencyVersion) {
7901
- const version = dependencyVersion("eslint");
7697
+ function hasEslint(version) {
7902
7698
  return !!version && version.startsWith(SUPPORTED_ESLINT_VERSION);
7903
7699
  }
7904
7700
 
7905
- var storybook = defineAdder({
7701
+ var storybook = defineAddon({
7906
7702
  id: "storybook",
7907
- environments: { kit: true, svelte: true },
7908
7703
  homepage: "https://storybook.js.org",
7909
7704
  options: {},
7910
- packages: [],
7911
- scripts: [
7912
- {
7913
- description: "applies storybook",
7914
- args: ["storybook@8.3.6", "init", "--skip-install", "--no-dev"],
7915
- stdio: "inherit"
7916
- }
7917
- ],
7918
- files: []
7705
+ run: async ({ sv }) => {
7706
+ await sv.execute(["storybook@latest", "init", "--skip-install", "--no-dev"], "inherit");
7707
+ }
7919
7708
  });
7920
7709
 
7921
7710
  function addImports(ast, imports) {
@@ -7959,13 +7748,7 @@ const plugins = [
7959
7748
  identifier: "aspectRatio"
7960
7749
  }
7961
7750
  ];
7962
- const pluginPackages = plugins.map((x) => ({
7963
- name: x.package,
7964
- version: x.version,
7965
- dev: true,
7966
- condition: ({ options: options2 }) => options2.plugins.includes(x.id)
7967
- }));
7968
- const options$1 = defineAdderOptions({
7751
+ const options$1 = defineAddonOptions({
7969
7752
  plugins: {
7970
7753
  type: "multiselect",
7971
7754
  question: "Which plugins would you like to add?",
@@ -7973,102 +7756,86 @@ const options$1 = defineAdderOptions({
7973
7756
  default: []
7974
7757
  }
7975
7758
  });
7976
- var tailwindcss = defineAdder({
7759
+ var tailwindcss = defineAddon({
7977
7760
  id: "tailwindcss",
7978
7761
  alias: "tailwind",
7979
- environments: { svelte: true, kit: true },
7980
7762
  homepage: "https://tailwindcss.com",
7981
7763
  options: options$1,
7982
- packages: [
7983
- { name: "tailwindcss", version: "^3.4.9", dev: true },
7984
- { name: "autoprefixer", version: "^10.4.20", dev: true },
7985
- {
7986
- name: "prettier-plugin-tailwindcss",
7987
- version: "^0.6.5",
7988
- dev: true,
7989
- condition: ({ dependencyVersion }) => Boolean(dependencyVersion("prettier"))
7990
- },
7991
- ...pluginPackages
7992
- ],
7993
- files: [
7994
- {
7995
- name: ({ typescript }) => `tailwind.config.${typescript ? "ts" : "js"}`,
7996
- content: ({ options: options2, typescript, content }) => {
7997
- const { ast, generateCode } = parseScript(content);
7998
- let root;
7999
- const rootExport = object$1.createEmpty();
8000
- if (typescript) {
8001
- imports.addNamed(ast, "tailwindcss", { Config: "Config" }, true);
8002
- root = common.satisfiesExpression(rootExport, "Config");
8003
- }
8004
- const { astNode: exportDeclaration, value: node } = exports$1.defaultExport(
8005
- ast,
8006
- root ?? rootExport
8007
- );
8008
- const config = node.type === "TSSatisfiesExpression" ? node.expression : node;
8009
- if (config.type !== "ObjectExpression") {
8010
- throw new Error(`Unexpected tailwind config shape: ${config.type}`);
8011
- }
8012
- if (!typescript) {
8013
- common.addJsDocTypeComment(exportDeclaration, "import('tailwindcss').Config");
8014
- }
8015
- const contentArray = object$1.property(config, "content", array$1.createEmpty());
8016
- array$1.push(contentArray, "./src/**/*.{html,js,svelte,ts}");
8017
- const themeObject = object$1.property(config, "theme", object$1.createEmpty());
8018
- object$1.property(themeObject, "extend", object$1.createEmpty());
8019
- const pluginsArray = object$1.property(config, "plugins", array$1.createEmpty());
8020
- for (const plugin of plugins) {
8021
- if (!options2.plugins.includes(plugin.id)) continue;
8022
- imports.addDefault(ast, plugin.package, plugin.identifier);
8023
- array$1.push(pluginsArray, { type: "Identifier", name: plugin.identifier });
8024
- }
8025
- return generateCode();
8026
- }
8027
- },
8028
- {
8029
- name: () => "postcss.config.js",
8030
- content: ({ content }) => {
8031
- const { ast, generateCode } = parseScript(content);
8032
- const { value: rootObject } = exports$1.defaultExport(ast, object$1.createEmpty());
8033
- const pluginsObject = object$1.property(rootObject, "plugins", object$1.createEmpty());
8034
- object$1.property(pluginsObject, "tailwindcss", object$1.createEmpty());
8035
- object$1.property(pluginsObject, "autoprefixer", object$1.createEmpty());
8036
- return generateCode();
7764
+ run: ({ sv, options: options2, typescript, kit, dependencyVersion }) => {
7765
+ const ext = typescript ? "ts" : "js";
7766
+ const prettierInstalled = Boolean(dependencyVersion("prettier"));
7767
+ sv.devDependency("tailwindcss", "^3.4.9");
7768
+ sv.devDependency("autoprefixer", "^10.4.20");
7769
+ if (prettierInstalled) sv.devDependency("prettier-plugin-tailwindcss", "^0.6.5");
7770
+ for (const plugin of plugins) {
7771
+ if (!options2.plugins.includes(plugin.id)) continue;
7772
+ sv.dependency(plugin.package, plugin.version);
7773
+ }
7774
+ sv.file(`tailwind.config.${ext}`, (content) => {
7775
+ const { ast, generateCode } = parseScript(content);
7776
+ let root;
7777
+ const rootExport = object$1.createEmpty();
7778
+ if (typescript) {
7779
+ imports.addNamed(ast, "tailwindcss", { Config: "Config" }, true);
7780
+ root = common.satisfiesExpression(rootExport, "Config");
7781
+ }
7782
+ const { astNode: exportDeclaration, value: node } = exports$1.defaultExport(
7783
+ ast,
7784
+ root ?? rootExport
7785
+ );
7786
+ const config = node.type === "TSSatisfiesExpression" ? node.expression : node;
7787
+ if (config.type !== "ObjectExpression") {
7788
+ throw new Error(`Unexpected tailwind config shape: ${config.type}`);
7789
+ }
7790
+ if (!typescript) {
7791
+ common.addJsDocTypeComment(exportDeclaration, "import('tailwindcss').Config");
7792
+ }
7793
+ const contentArray = object$1.property(config, "content", array$1.createEmpty());
7794
+ array$1.push(contentArray, "./src/**/*.{html,js,svelte,ts}");
7795
+ const themeObject = object$1.property(config, "theme", object$1.createEmpty());
7796
+ object$1.property(themeObject, "extend", object$1.createEmpty());
7797
+ const pluginsArray = object$1.property(config, "plugins", array$1.createEmpty());
7798
+ for (const plugin of plugins) {
7799
+ if (!options2.plugins.includes(plugin.id)) continue;
7800
+ imports.addDefault(ast, plugin.package, plugin.identifier);
7801
+ array$1.push(pluginsArray, { type: "Identifier", name: plugin.identifier });
7802
+ }
7803
+ return generateCode();
7804
+ });
7805
+ sv.file("postcss.config.js", (content) => {
7806
+ const { ast, generateCode } = parseScript(content);
7807
+ const { value: rootObject } = exports$1.defaultExport(ast, object$1.createEmpty());
7808
+ const pluginsObject = object$1.property(rootObject, "plugins", object$1.createEmpty());
7809
+ object$1.property(pluginsObject, "tailwindcss", object$1.createEmpty());
7810
+ object$1.property(pluginsObject, "autoprefixer", object$1.createEmpty());
7811
+ return generateCode();
7812
+ });
7813
+ sv.file("src/app.css", (content) => {
7814
+ const layerImports = ["base", "components", "utilities"].map(
7815
+ (layer) => `tailwindcss/${layer}`
7816
+ );
7817
+ if (layerImports.every((i) => content.includes(i))) {
7818
+ return content;
8037
7819
  }
8038
- },
8039
- {
8040
- name: () => "src/app.css",
8041
- content: ({ content }) => {
8042
- const layerImports = ["base", "components", "utilities"].map(
8043
- (layer) => `tailwindcss/${layer}`
8044
- );
8045
- if (layerImports.every((i) => content.includes(i))) {
8046
- return content;
8047
- }
8048
- const { ast, generateCode } = parseCss(content);
8049
- const originalFirst = ast.first;
8050
- const specifiers = layerImports.map((i) => `'${i}'`);
8051
- const nodes = addImports(ast, specifiers);
8052
- if (originalFirst !== ast.first && originalFirst?.type === "atrule" && originalFirst.name === "import") {
8053
- originalFirst.raws.before = "\n";
8054
- }
8055
- nodes.shift();
8056
- nodes.forEach((n) => n.raws.before = "\n");
8057
- return generateCode();
7820
+ const { ast, generateCode } = parseCss(content);
7821
+ const originalFirst = ast.first;
7822
+ const specifiers = layerImports.map((i) => `'${i}'`);
7823
+ const nodes = addImports(ast, specifiers);
7824
+ if (originalFirst !== ast.first && originalFirst?.type === "atrule" && originalFirst.name === "import") {
7825
+ originalFirst.raws.before = "\n";
8058
7826
  }
8059
- },
8060
- {
8061
- name: () => "src/App.svelte",
8062
- content: ({ content, typescript }) => {
7827
+ nodes.shift();
7828
+ nodes.forEach((n) => n.raws.before = "\n");
7829
+ return generateCode();
7830
+ });
7831
+ if (!kit) {
7832
+ sv.file("src/App.svelte", (content) => {
8063
7833
  const { script, generateCode } = parseSvelte(content, { typescript });
8064
7834
  imports.addEmpty(script.ast, "./app.css");
8065
7835
  return generateCode({ script: script.generateCode() });
8066
- },
8067
- condition: ({ kit }) => !kit
8068
- },
8069
- {
8070
- name: ({ kit }) => `${kit?.routesDirectory}/+layout.svelte`,
8071
- content: ({ content, typescript, dependencyVersion }) => {
7836
+ });
7837
+ } else {
7838
+ sv.file(`${kit?.routesDirectory}/+layout.svelte`, (content) => {
8072
7839
  const { script, template, generateCode } = parseSvelte(content, { typescript });
8073
7840
  imports.addEmpty(script.ast, "../app.css");
8074
7841
  if (content.length === 0) {
@@ -8080,103 +7847,91 @@ var tailwindcss = defineAdder({
8080
7847
  script: script.generateCode(),
8081
7848
  template: content.length === 0 ? template.generateCode() : void 0
8082
7849
  });
8083
- },
8084
- condition: ({ kit }) => Boolean(kit)
8085
- },
8086
- {
8087
- name: () => ".prettierrc",
8088
- content: ({ content }) => {
7850
+ });
7851
+ }
7852
+ if (dependencyVersion("prettier")) {
7853
+ sv.file(".prettierrc", (content) => {
8089
7854
  const { data, generateCode } = parseJson(content);
8090
7855
  const PLUGIN_NAME = "prettier-plugin-tailwindcss";
8091
7856
  data.plugins ?? (data.plugins = []);
8092
7857
  const plugins2 = data.plugins;
8093
7858
  if (!plugins2.includes(PLUGIN_NAME)) plugins2.push(PLUGIN_NAME);
8094
7859
  return generateCode();
8095
- },
8096
- condition: ({ dependencyVersion }) => Boolean(dependencyVersion("prettier"))
7860
+ });
8097
7861
  }
8098
- ]
7862
+ }
8099
7863
  });
8100
7864
 
8101
- var vitest = defineAdder({
7865
+ var vitest = defineAddon({
8102
7866
  id: "vitest",
8103
- environments: { svelte: true, kit: true },
8104
7867
  homepage: "https://vitest.dev",
8105
7868
  options: {},
8106
- packages: [{ name: "vitest", version: "^2.0.4", dev: true }],
8107
- files: [
8108
- {
8109
- name: () => "package.json",
8110
- content: ({ content }) => {
8111
- const { data, generateCode } = parseJson(content);
8112
- data.scripts ?? (data.scripts = {});
8113
- const scripts = data.scripts;
8114
- const TEST_CMD = "vitest";
8115
- const RUN_TEST = "npm run test:unit -- --run";
8116
- scripts["test:unit"] ?? (scripts["test:unit"] = TEST_CMD);
8117
- scripts["test"] ?? (scripts["test"] = RUN_TEST);
8118
- if (!scripts["test"].includes(RUN_TEST)) scripts["test"] += ` && ${RUN_TEST}`;
8119
- return generateCode();
8120
- }
8121
- },
8122
- {
8123
- name: ({ typescript }) => `src/demo.spec.${typescript ? "ts" : "js"}`,
8124
- content: ({ content }) => {
8125
- if (content) return content;
8126
- return dedent`
8127
- import { describe, it, expect } from 'vitest';
8128
-
8129
- describe('sum test', () => {
8130
- it('adds 1 + 2 to equal 3', () => {
8131
- expect(1 + 2).toBe(3);
8132
- });
7869
+ run: ({ sv, typescript }) => {
7870
+ const ext = typescript ? "ts" : "js";
7871
+ sv.devDependency("vitest", "^2.0.4");
7872
+ sv.file("package.json", (content) => {
7873
+ const { data, generateCode } = parseJson(content);
7874
+ data.scripts ?? (data.scripts = {});
7875
+ const scripts = data.scripts;
7876
+ const TEST_CMD = "vitest";
7877
+ const RUN_TEST = "npm run test:unit -- --run";
7878
+ scripts["test:unit"] ?? (scripts["test:unit"] = TEST_CMD);
7879
+ scripts["test"] ?? (scripts["test"] = RUN_TEST);
7880
+ if (!scripts["test"].includes(RUN_TEST)) scripts["test"] += ` && ${RUN_TEST}`;
7881
+ return generateCode();
7882
+ });
7883
+ sv.file(`src/demo.spec.${ext}`, (content) => {
7884
+ if (content) return content;
7885
+ return dedent`
7886
+ import { describe, it, expect } from 'vitest';
7887
+
7888
+ describe('sum test', () => {
7889
+ it('adds 1 + 2 to equal 3', () => {
7890
+ expect(1 + 2).toBe(3);
8133
7891
  });
8134
- `;
7892
+ });
7893
+ `;
7894
+ });
7895
+ sv.file(`vite.config.${ext}`, (content) => {
7896
+ const { ast, generateCode } = parseScript(content);
7897
+ const importDecls = ast.body.filter((n) => n.type === "ImportDeclaration");
7898
+ const defineConfigImportDecl = importDecls.find(
7899
+ (importDecl) => (importDecl.source.value === "vite" || importDecl.source.value === "vitest/config") && importDecl.importKind === "value" && importDecl.specifiers?.some(
7900
+ (specifier) => specifier.type === "ImportSpecifier" && specifier.imported.name === "defineConfig"
7901
+ )
7902
+ );
7903
+ if (defineConfigImportDecl?.specifiers?.length === 1) {
7904
+ const idxToRemove = ast.body.indexOf(defineConfigImportDecl);
7905
+ ast.body.splice(idxToRemove, 1);
7906
+ } else {
7907
+ const idxToRemove = defineConfigImportDecl?.specifiers?.findIndex(
7908
+ (s) => s.type === "ImportSpecifier" && s.imported.name === "defineConfig"
7909
+ );
7910
+ if (idxToRemove) defineConfigImportDecl?.specifiers?.splice(idxToRemove, 1);
8135
7911
  }
8136
- },
8137
- {
8138
- name: ({ typescript }) => `vite.config.${typescript ? "ts" : "js"}`,
8139
- content: ({ content }) => {
8140
- const { ast, generateCode } = parseScript(content);
8141
- const importDecls = ast.body.filter((n) => n.type === "ImportDeclaration");
8142
- const defineConfigImportDecl = importDecls.find(
8143
- (importDecl) => (importDecl.source.value === "vite" || importDecl.source.value === "vitest/config") && importDecl.importKind === "value" && importDecl.specifiers?.some(
8144
- (specifier) => specifier.type === "ImportSpecifier" && specifier.imported.name === "defineConfig"
8145
- )
7912
+ const config = common.expressionFromString("defineConfig({})");
7913
+ const defaultExport = exports$1.defaultExport(ast, config);
7914
+ const test = object$1.create({
7915
+ include: common.expressionFromString("['src/**/*.{test,spec}.{js,ts}']")
7916
+ });
7917
+ if (defaultExport.value.type === "CallExpression" && defaultExport.value.arguments[0]?.type === "ObjectExpression") {
7918
+ const importSpecifier = defineConfigImportDecl?.specifiers?.find(
7919
+ (sp) => sp.type === "ImportSpecifier" && sp.imported.name === "defineConfig"
8146
7920
  );
8147
- if (defineConfigImportDecl?.specifiers?.length === 1) {
8148
- const idxToRemove = ast.body.indexOf(defineConfigImportDecl);
8149
- ast.body.splice(idxToRemove, 1);
8150
- } else {
8151
- const idxToRemove = defineConfigImportDecl?.specifiers?.findIndex(
8152
- (s) => s.type === "ImportSpecifier" && s.imported.name === "defineConfig"
8153
- );
8154
- if (idxToRemove) defineConfigImportDecl?.specifiers?.splice(idxToRemove, 1);
8155
- }
8156
- const config = common.expressionFromString("defineConfig({})");
8157
- const defaultExport = exports$1.defaultExport(ast, config);
8158
- const test = object$1.create({
8159
- include: common.expressionFromString("['src/**/*.{test,spec}.{js,ts}']")
8160
- });
8161
- if (defaultExport.value.type === "CallExpression" && defaultExport.value.arguments[0]?.type === "ObjectExpression") {
8162
- const importSpecifier = defineConfigImportDecl?.specifiers?.find(
8163
- (sp) => sp.type === "ImportSpecifier" && sp.imported.name === "defineConfig"
8164
- );
8165
- const defineConfigAlias = importSpecifier?.local?.name ?? "defineConfig";
8166
- imports.addNamed(ast, "vitest/config", { defineConfig: defineConfigAlias });
8167
- object$1.properties(defaultExport.value.arguments[0], { test });
8168
- } else if (defaultExport.value.type === "ObjectExpression") {
8169
- object$1.properties(defaultExport.value, { test });
8170
- } else {
8171
- log.warn("Unexpected vite config for vitest adder. Could not update.");
8172
- }
8173
- return generateCode();
7921
+ const defineConfigAlias = importSpecifier?.local?.name ?? "defineConfig";
7922
+ imports.addNamed(ast, "vitest/config", { defineConfig: defineConfigAlias });
7923
+ object$1.properties(defaultExport.value.arguments[0], { test });
7924
+ } else if (defaultExport.value.type === "ObjectExpression") {
7925
+ object$1.properties(defaultExport.value, { test });
7926
+ } else {
7927
+ log.warn("Unexpected vite config for vitest add-on. Could not update.");
8174
7928
  }
8175
- }
8176
- ]
7929
+ return generateCode();
7930
+ });
7931
+ }
8177
7932
  });
8178
7933
 
8179
- const officialAdders = [
7934
+ const officialAddons = [
8180
7935
  prettier,
8181
7936
  eslint,
8182
7937
  vitest,
@@ -8188,18 +7943,18 @@ const officialAdders = [
8188
7943
  paraglide,
8189
7944
  storybook
8190
7945
  ];
8191
- function getAdderDetails(id) {
8192
- const details = officialAdders.find((a) => a.id === id);
7946
+ function getAddonDetails(id) {
7947
+ const details = officialAddons.find((a) => a.id === id);
8193
7948
  if (!details) {
8194
- throw new Error(`Invalid adder: ${id}`);
7949
+ throw new Error(`Invalid add-on: ${id}`);
8195
7950
  }
8196
7951
  return details;
8197
7952
  }
8198
7953
 
8199
7954
  function __variableDynamicImportRuntime0__(path) {
8200
7955
  switch (path) {
8201
- case '../../../community-adders/unocss.ts': return import('./unocss-CQk-PWUl.js');
8202
- case '../../../community-adders/unplugin-icons.ts': return import('./unplugin-icons-D6icB7Q_.js');
7956
+ case '../../../community-addons/unocss.ts': return import('./unocss-CQk-PWUl.js');
7957
+ case '../../../community-addons/unplugin-icons.ts': return import('./unplugin-icons-D6icB7Q_.js');
8203
7958
  default: return new Promise(function(resolve, reject) {
8204
7959
  (typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
8205
7960
  reject.bind(null, new Error("Unknown variable dynamic import: " + path))
@@ -8207,11 +7962,23 @@ function __variableDynamicImportRuntime0__(path) {
8207
7962
  })
8208
7963
  }
8209
7964
  }
8210
- const communityAdderIds = ["unocss","unplugin-icons"];async function getCommunityAdder(name) {
8211
- const { default: details } = await __variableDynamicImportRuntime0__(`../../../community-adders/${name}.ts`);
7965
+ const communityAddonIds = ["unocss","unplugin-icons"];async function getCommunityAddon(name) {
7966
+ const { default: details } = await __variableDynamicImportRuntime0__(`../../../community-addons/${name}.ts`);
8212
7967
  return details;
8213
7968
  }
8214
7969
 
7970
+ var __defProp = Object.defineProperty;
7971
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7972
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7973
+ class UnsupportedError extends Error {
7974
+ constructor(reasons) {
7975
+ super();
7976
+ __publicField(this, "name", "Unsupported Environment");
7977
+ __publicField(this, "reasons", []);
7978
+ this.reasons = reasons;
7979
+ }
7980
+ }
7981
+
8215
7982
  const NO_PREFIX = "--no-";
8216
7983
  let options = [];
8217
7984
  function getLongFlag(flags) {
@@ -8263,58 +8030,23 @@ async function runCommand(action) {
8263
8030
  await action();
8264
8031
  outro("You're all set!");
8265
8032
  } catch (e) {
8266
- cancel("Operation failed.");
8267
- if (e instanceof Error) {
8268
- console.error(e.stack ?? e);
8033
+ if (e instanceof UnsupportedError) {
8034
+ const padding = getPadding(e.reasons.map((r) => r.id));
8035
+ const message = e.reasons.map((r) => ` ${r.id.padEnd(padding)} ${pc.red(r.reason)}`).join("\n");
8036
+ log$1.error(`${e.name}
8037
+
8038
+ ${message}`);
8039
+ log$1.message();
8040
+ } else if (e instanceof Error) {
8041
+ log$1.error(e.stack ?? String(e));
8042
+ log$1.message();
8269
8043
  }
8044
+ cancel("Operation failed.");
8270
8045
  }
8271
8046
  }
8272
-
8273
- function getGlobalPreconditions(cwd, projectType, adders) {
8274
- return {
8275
- name: "global checks",
8276
- preconditions: [
8277
- {
8278
- name: "clean working directory",
8279
- run: async () => {
8280
- try {
8281
- const { stdout } = await be("git", ["status", "--short"], {
8282
- nodeOptions: { cwd },
8283
- throwOnError: true
8284
- });
8285
- if (stdout) {
8286
- return { success: false, message: "Found modified files" };
8287
- }
8288
- return { success: true, message: void 0 };
8289
- } catch {
8290
- return { success: true, message: "Not a git repository" };
8291
- }
8292
- }
8293
- },
8294
- {
8295
- name: "supported environments",
8296
- run: () => {
8297
- const addersForInvalidEnvironment = adders.filter((a) => {
8298
- const supportedEnvironments = a.environments;
8299
- if (projectType === "kit" && !supportedEnvironments.kit) return true;
8300
- if (projectType === "svelte" && !supportedEnvironments.svelte) return true;
8301
- return false;
8302
- });
8303
- if (addersForInvalidEnvironment.length === 0) {
8304
- return { success: true, message: void 0 };
8305
- }
8306
- const messages = addersForInvalidEnvironment.map((a) => {
8307
- if (projectType === "kit") {
8308
- return `'${a.id}' does not support SvelteKit`;
8309
- } else {
8310
- return `'${a.id}' requires SvelteKit`;
8311
- }
8312
- });
8313
- throw new Error(messages.join("\n"));
8314
- }
8315
- }
8316
- ]
8317
- };
8047
+ function getPadding(lines) {
8048
+ const lengths = lines.map((s) => s.length);
8049
+ return Math.max(...lengths);
8318
8050
  }
8319
8051
 
8320
8052
  var tarStream = {};
@@ -11479,14 +11211,14 @@ function verifyPackage(pkg, specifier) {
11479
11211
  const deps = { ...pkg.dependencies, ...pkg.peerDependencies };
11480
11212
  if (!deps["@sveltejs/cli-core"]) {
11481
11213
  throw new Error(
11482
- `Invalid adder package specified: '${specifier}' is missing a dependency on '@sveltejs/cli-core' in its 'package.json'`
11214
+ `Invalid add-on package specified: '${specifier}' is missing a dependency on '@sveltejs/cli-core' in its 'package.json'`
11483
11215
  );
11484
11216
  }
11485
11217
  for (const dep of Object.keys(deps)) {
11486
11218
  if (dep === "@sveltejs/cli-core") continue;
11487
11219
  throw new Error(
11488
- `Invalid adder package detected: '${specifier}'
11489
- Community adders should not have any external 'dependencies' besides '@sveltejs/cli-core'. Consider bundling your dependencies if they are necessary`
11220
+ `Invalid add-on package detected: '${specifier}'
11221
+ Community addons should not have any external 'dependencies' besides '@sveltejs/cli-core'. Consider bundling your dependencies if they are necessary`
11490
11222
  );
11491
11223
  }
11492
11224
  }
@@ -11562,8 +11294,45 @@ async function fetchPackageJSON(packageName) {
11562
11294
  return await resp.json();
11563
11295
  }
11564
11296
 
11565
- const AddersSchema = array(string());
11566
- const AdderOptionFlagsSchema = object({
11297
+ function getGlobalPreconditions(cwd, addons, addonSetupResult) {
11298
+ return {
11299
+ name: "global checks",
11300
+ preconditions: [
11301
+ {
11302
+ name: "clean working directory",
11303
+ run: async () => {
11304
+ try {
11305
+ const { stdout } = await be("git", ["status", "--short"], {
11306
+ nodeOptions: { cwd },
11307
+ throwOnError: true
11308
+ });
11309
+ if (stdout) {
11310
+ return { success: false, message: "Found modified files" };
11311
+ }
11312
+ return { success: true, message: void 0 };
11313
+ } catch {
11314
+ return { success: true, message: "Not a git repository" };
11315
+ }
11316
+ }
11317
+ },
11318
+ {
11319
+ name: "unsupported add-ons",
11320
+ run: () => {
11321
+ const reasons = addons.flatMap(
11322
+ (a) => addonSetupResult[a.id].unsupported.map((reason) => ({ id: a.id, reason }))
11323
+ );
11324
+ if (reasons.length === 0) {
11325
+ return { success: true, message: void 0 };
11326
+ }
11327
+ throw new UnsupportedError(reasons);
11328
+ }
11329
+ }
11330
+ ]
11331
+ };
11332
+ }
11333
+
11334
+ const AddonsSchema = array(string());
11335
+ const AddonOptionFlagsSchema = object({
11567
11336
  tailwindcss: optional(array(string())),
11568
11337
  drizzle: optional(array(string())),
11569
11338
  lucia: optional(array(string())),
@@ -11573,15 +11342,15 @@ const OptionsSchema$1 = strictObject({
11573
11342
  cwd: string(),
11574
11343
  install: boolean(),
11575
11344
  preconditions: boolean(),
11576
- community: optional(union([AddersSchema, boolean()])),
11577
- ...AdderOptionFlagsSchema.entries
11345
+ community: optional(union([AddonsSchema, boolean()])),
11346
+ ...AddonOptionFlagsSchema.entries
11578
11347
  });
11579
- const aliases = officialAdders.map((c) => c.alias).filter((v2) => v2 !== void 0);
11580
- const addersOptions = getAdderOptionFlags();
11348
+ const aliases = officialAddons.map((c) => c.alias).filter((v2) => v2 !== void 0);
11349
+ const addonsOptions = getAddonOptionFlags();
11581
11350
  const communityDetails = [];
11582
11351
  const defaultPkgPath = up();
11583
11352
  const defaultCwd = defaultPkgPath ? path$2.dirname(defaultPkgPath) : void 0;
11584
- const add = new Command("add").description("applies specified add-ons into a project").argument("[add-on...]", "add-ons to install").option("-C, --cwd <path>", "path to working directory", defaultCwd).option("--no-install", "skip installing dependencies").option("--no-preconditions", "skip validating preconditions").configureHelp(helpConfig).action((adderArgs, opts) => {
11353
+ const add = new Command("add").description("applies specified add-ons into a project").argument("[add-on...]", "add-ons to install").option("-C, --cwd <path>", "path to working directory", defaultCwd).option("--no-install", "skip installing dependencies").option("--no-preconditions", "skip validating preconditions").configureHelp(helpConfig).action((addonArgs, opts) => {
11585
11354
  if (opts.cwd === void 0) {
11586
11355
  console.error(
11587
11356
  "Invalid workspace: Please verify that you are inside of a Svelte project. You can also specify the working directory with `--cwd <path>`"
@@ -11593,43 +11362,43 @@ const add = new Command("add").description("applies specified add-ons into a pro
11593
11362
  );
11594
11363
  process$1$1.exit(1);
11595
11364
  }
11596
- const specifiedAdders = parse(AddersSchema, adderArgs);
11365
+ const specifiedAddons = parse(AddonsSchema, addonArgs);
11597
11366
  const options = parse(OptionsSchema$1, opts);
11598
- const adderIds = officialAdders.map((adder) => adder.id);
11599
- const invalidAdders = specifiedAdders.filter(
11600
- (a) => !adderIds.includes(a) && !aliases.includes(a)
11367
+ const addonIds = officialAddons.map((addon) => addon.id);
11368
+ const invalidAddons = specifiedAddons.filter(
11369
+ (a) => !addonIds.includes(a) && !aliases.includes(a)
11601
11370
  );
11602
- if (invalidAdders.length > 0) {
11603
- console.error(`Invalid adders specified: ${invalidAdders.join(", ")}`);
11371
+ if (invalidAddons.length > 0) {
11372
+ console.error(`Invalid add-ons specified: ${invalidAddons.join(", ")}`);
11604
11373
  process$1$1.exit(1);
11605
11374
  }
11606
- const selectedAdders = transformAliases(specifiedAdders);
11375
+ const selectedAddons = transformAliases(specifiedAddons);
11607
11376
  runCommand(async () => {
11608
- const { nextSteps } = await runAddCommand(options, selectedAdders);
11377
+ const { nextSteps } = await runAddCommand(options, selectedAddons);
11609
11378
  if (nextSteps) box(nextSteps, "Next steps");
11610
11379
  });
11611
11380
  });
11612
- for (const option of addersOptions) {
11381
+ for (const option of addonsOptions) {
11613
11382
  add.addOption(option);
11614
11383
  }
11615
- async function runAddCommand(options, selectedAdderIds) {
11384
+ async function runAddCommand(options, selectedAddonIds) {
11616
11385
  var _a;
11617
- const selectedAdders = selectedAdderIds.map((id) => ({
11386
+ const selectedAddons = selectedAddonIds.map((id) => ({
11618
11387
  type: "official",
11619
- adder: getAdderDetails(id)
11388
+ addon: getAddonDetails(id)
11620
11389
  }));
11621
11390
  const official = {};
11622
11391
  const community = {};
11623
- for (const adderOption of addersOptions) {
11624
- const adderId = adderOption.attributeName();
11625
- const specifiedOptions = options[adderId];
11392
+ for (const addonOption of addonsOptions) {
11393
+ const addonId = addonOption.attributeName();
11394
+ const specifiedOptions = options[addonId];
11626
11395
  if (!specifiedOptions) continue;
11627
- const details = getAdderDetails(adderId);
11628
- if (!selectedAdders.find((d) => d.adder === details)) {
11629
- selectedAdders.push({ type: "official", adder: details });
11396
+ const details2 = getAddonDetails(addonId);
11397
+ if (!selectedAddons.find((d) => d.addon === details2)) {
11398
+ selectedAddons.push({ type: "official", addon: details2 });
11630
11399
  }
11631
- official[adderId] ?? (official[adderId] = {});
11632
- const optionEntries = Object.entries(details.options);
11400
+ official[addonId] ?? (official[addonId] = {});
11401
+ const optionEntries = Object.entries(details2.options);
11633
11402
  for (const specifiedOption of specifiedOptions) {
11634
11403
  if (!specifiedOption || specifiedOption === "none") continue;
11635
11404
  const optionEntry = optionEntries.find(([id, question2]) => {
@@ -11641,44 +11410,44 @@ async function runAddCommand(options, selectedAdderIds) {
11641
11410
  }
11642
11411
  });
11643
11412
  if (!optionEntry) {
11644
- const { choices } = getOptionChoices(details);
11413
+ const { choices } = getOptionChoices(details2);
11645
11414
  throw new Error(
11646
- `Invalid '--${adderId}' option: '${specifiedOption}'
11415
+ `Invalid '--${addonId}' option: '${specifiedOption}'
11647
11416
  Available options: ${choices.join(", ")}`
11648
11417
  );
11649
11418
  }
11650
11419
  const [questionId, question] = optionEntry;
11651
- let existingOption = official[adderId][questionId];
11420
+ let existingOption = official[addonId][questionId];
11652
11421
  if (existingOption !== void 0) {
11653
11422
  if (typeof existingOption === "boolean") {
11654
11423
  existingOption = existingOption ? questionId : `no-${questionId}`;
11655
11424
  }
11656
11425
  throw new Error(
11657
- `Conflicting '--${adderId}' option: '${specifiedOption}' conflicts with '${existingOption}'`
11426
+ `Conflicting '--${addonId}' option: '${specifiedOption}' conflicts with '${existingOption}'`
11658
11427
  );
11659
11428
  }
11660
- official[adderId][questionId] = question.type === "boolean" ? !specifiedOption.startsWith("no-") : specifiedOption;
11429
+ official[addonId][questionId] = question.type === "boolean" ? !specifiedOption.startsWith("no-") : specifiedOption;
11661
11430
  }
11662
- for (const [id, question] of Object.entries(details.options)) {
11663
- if (question.condition?.(official[adderId]) !== false) {
11664
- (_a = official[adderId])[id] ?? (_a[id] = question.default);
11431
+ for (const [id, question] of Object.entries(details2.options)) {
11432
+ if (question.condition?.(official[addonId]) !== false) {
11433
+ (_a = official[addonId])[id] ?? (_a[id] = question.default);
11665
11434
  } else {
11666
- if (official[adderId][id] !== void 0) {
11435
+ if (official[addonId][id] !== void 0) {
11667
11436
  throw new Error(
11668
- `Incompatible '--${adderId}' option specified: '${official[adderId][id]}'`
11437
+ `Incompatible '--${addonId}' option specified: '${official[addonId][id]}'`
11669
11438
  );
11670
11439
  }
11671
11440
  }
11672
11441
  }
11673
11442
  }
11674
11443
  if (options.community === true) {
11675
- const communityAdders = await Promise.all(
11676
- communityAdderIds.map(async (id) => await getCommunityAdder(id))
11444
+ const communityAddons = await Promise.all(
11445
+ communityAddonIds.map(async (id) => await getCommunityAddon(id))
11677
11446
  );
11678
- const promptOptions = communityAdders.map((adder) => ({
11679
- value: adder.id,
11680
- label: adder.id,
11681
- hint: "https://www.npmjs.com/package/" + adder.id
11447
+ const promptOptions = communityAddons.map((addon) => ({
11448
+ value: addon.id,
11449
+ label: addon.id,
11450
+ hint: "https://www.npmjs.com/package/" + addon.id
11682
11451
  }));
11683
11452
  const selected = await multiselect({
11684
11453
  message: "Which community tools would you like to add to your project?",
@@ -11689,35 +11458,35 @@ Available options: ${choices.join(", ")}`
11689
11458
  cancel("Operation cancelled.");
11690
11459
  process$1$1.exit(1);
11691
11460
  } else if (selected.length === 0) {
11692
- cancel("No adders selected. Exiting.");
11461
+ cancel("No add-ons selected. Exiting.");
11693
11462
  process$1$1.exit(1);
11694
11463
  }
11695
11464
  options.community = selected;
11696
11465
  }
11697
11466
  if (Array.isArray(options.community) && options.community.length > 0) {
11698
- const adders = options.community.map((id) => {
11467
+ const addons = options.community.map((id) => {
11699
11468
  const hasDirective = Object.values(Directive).some((directive) => id.startsWith(directive));
11700
11469
  if (hasDirective) return id;
11701
- const validAdder = communityAdderIds.includes(id);
11702
- if (!validAdder) {
11470
+ const validAddon = communityAddonIds.includes(id);
11471
+ if (!validAddon) {
11703
11472
  throw new Error(
11704
- `Invalid community adder specified: '${id}'
11705
- Available options: ${communityAdderIds.join(", ")}`
11473
+ `Invalid community add-on specified: '${id}'
11474
+ Available options: ${communityAddonIds.join(", ")}`
11706
11475
  );
11707
11476
  }
11708
11477
  return id;
11709
11478
  });
11710
11479
  const { start, stop } = spinner();
11711
11480
  try {
11712
- start("Resolving community adder packages");
11481
+ start("Resolving community add-on packages");
11713
11482
  const pkgs = await Promise.all(
11714
- adders.map(async (id) => {
11483
+ addons.map(async (id) => {
11715
11484
  return await getPackageJSON({ cwd: options.cwd, packageName: id });
11716
11485
  })
11717
11486
  );
11718
- stop("Resolved community adder packages");
11487
+ stop("Resolved community add-on packages");
11719
11488
  log$1.warn(
11720
- "The Svelte maintainers have not reviewed community adders for malicious code. Use at your discretion."
11489
+ "The Svelte maintainers have not reviewed community add-ons for malicious code. Use at your discretion."
11721
11490
  );
11722
11491
  const paddingName = getPadding(pkgs.map(({ pkg: pkg2 }) => pkg2.name));
11723
11492
  const paddingVersion = getPadding(pkgs.map(({ pkg: pkg2 }) => `(v${pkg2.version})`));
@@ -11733,70 +11502,60 @@ Available options: ${communityAdderIds.join(", ")}`
11733
11502
  cancel("Operation cancelled.");
11734
11503
  process$1$1.exit(1);
11735
11504
  }
11736
- start("Downloading community adder packages");
11737
- const details = await Promise.all(pkgs.map(async (opts) => downloadPackage(opts)));
11738
- for (const adder of details) {
11739
- const id = adder.id;
11505
+ start("Downloading community add-on packages");
11506
+ const details2 = await Promise.all(pkgs.map(async (opts) => downloadPackage(opts)));
11507
+ for (const addon of details2) {
11508
+ const id = addon.id;
11740
11509
  community[id] ?? (community[id] = {});
11741
- communityDetails.push(adder);
11742
- selectedAdders.push({ type: "community", adder });
11510
+ communityDetails.push(addon);
11511
+ selectedAddons.push({ type: "community", addon });
11743
11512
  }
11744
- stop("Downloaded community adder packages");
11513
+ stop("Downloaded community add-on packages");
11745
11514
  } catch (err) {
11746
- stop("Failed to resolve community adder packages", 1);
11515
+ stop("Failed to resolve community add-on packages", 1);
11747
11516
  throw err;
11748
11517
  }
11749
11518
  }
11750
- if (selectedAdders.length === 0) {
11751
- const workspace2 = createWorkspace({ cwd: options.cwd });
11752
- const projectType = workspace2.kit ? "kit" : "svelte";
11753
- const adderOptions = officialAdders.map((adder) => {
11754
- if (projectType === "kit" && !adder.environments.kit) return;
11755
- if (projectType === "svelte" && !adder.environments.svelte) return;
11756
- return {
11757
- label: adder.id,
11758
- value: adder.id,
11759
- hint: adder.homepage
11760
- };
11761
- }).filter((a) => !!a);
11519
+ let workspace = createWorkspace({ cwd: options.cwd });
11520
+ const addonSetupResults = setupAddons(officialAddons, workspace);
11521
+ if (selectedAddons.length === 0) {
11522
+ const addonOptions = officialAddons.filter(({ id }) => addonSetupResults[id].unsupported.length === 0).map(({ id, homepage }) => ({ label: id, value: id, hint: homepage }));
11762
11523
  const selected = await multiselect({
11763
11524
  message: `What would you like to add to your project? ${pc.dim("(use arrow keys / space bar)")}`,
11764
- options: adderOptions,
11525
+ options: addonOptions,
11765
11526
  required: false
11766
11527
  });
11767
11528
  if (isCancel(selected)) {
11768
11529
  cancel("Operation cancelled.");
11769
11530
  process$1$1.exit(1);
11770
11531
  }
11771
- selected.forEach((id) => selectedAdders.push({ type: "official", adder: getAdderDetails(id) }));
11772
- }
11773
- for (const { adder } of selectedAdders) {
11774
- const dependents = adder.dependsOn?.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? [];
11775
- const workspace2 = createWorkspace({ cwd: options.cwd });
11776
- for (const depId of dependents) {
11777
- const dependent = officialAdders.find((a) => a.id === depId);
11778
- if (!dependent) throw new Error(`Adder '${adder.id}' depends on an invalid '${depId}'`);
11779
- let installed = false;
11780
- installed = dependent.packages.every(
11781
- // we'll skip the conditions since we don't have any options to supply it
11782
- (p2) => p2.condition !== void 0 || !!workspace2.dependencyVersion(p2.name)
11783
- );
11784
- if (installed) continue;
11532
+ for (const id of selected) {
11533
+ const addon = officialAddons.find((addon2) => addon2.id === id);
11534
+ selectedAddons.push({ type: "official", addon });
11535
+ }
11536
+ }
11537
+ for (const { addon } of selectedAddons) {
11538
+ workspace = createWorkspace(workspace);
11539
+ const setupResult = addonSetupResults[addon.id];
11540
+ const missingDependencies = setupResult.dependsOn.filter(
11541
+ (depId) => !selectedAddons.some((a) => a.addon.id === depId)
11542
+ );
11543
+ for (const depId of missingDependencies) {
11544
+ const dependency = officialAddons.find((a) => a.id === depId);
11545
+ if (!dependency) throw new Error(`'${addon.id}' depends on an invalid add-on: '${depId}'`);
11785
11546
  const install = await confirm({
11786
- message: `The ${pc.bold(pc.cyan(adder.id))} add-on requires ${pc.bold(pc.cyan(depId))} to also be setup. ${pc.green("Include it?")}`
11547
+ message: `The ${pc.bold(pc.cyan(addon.id))} add-on requires ${pc.bold(pc.cyan(depId))} to also be setup. ${pc.green("Include it?")}`
11787
11548
  });
11788
11549
  if (install !== true) {
11789
11550
  cancel("Operation cancelled.");
11790
11551
  process$1$1.exit(1);
11791
11552
  }
11792
- selectedAdders.push({ type: "official", adder: dependent });
11553
+ selectedAddons.push({ type: "official", addon: dependency });
11793
11554
  }
11794
11555
  }
11795
- if (options.preconditions && selectedAdders.length > 0) {
11796
- const { kit } = createWorkspace({ cwd: options.cwd });
11797
- const projectType = kit ? "kit" : "svelte";
11798
- const adders = selectedAdders.map(({ adder }) => adder);
11799
- const { preconditions } = getGlobalPreconditions(options.cwd, projectType, adders);
11556
+ if (options.preconditions && selectedAddons.length > 0) {
11557
+ const addons = selectedAddons.map(({ addon }) => addon);
11558
+ const { preconditions } = getGlobalPreconditions(options.cwd, addons, addonSetupResults);
11800
11559
  const fails = [];
11801
11560
  for (const condition of preconditions) {
11802
11561
  const { message, success } = await condition.run();
@@ -11815,19 +11574,19 @@ Available options: ${communityAdderIds.join(", ")}`
11815
11574
  }
11816
11575
  }
11817
11576
  }
11818
- for (const { adder, type } of selectedAdders) {
11819
- const adderId = adder.id;
11820
- const questionPrefix = selectedAdders.length > 1 ? `${adder.id}: ` : "";
11577
+ for (const { addon, type } of selectedAddons) {
11578
+ const addonId = addon.id;
11579
+ const questionPrefix = selectedAddons.length > 1 ? `${addon.id}: ` : "";
11821
11580
  let values = {};
11822
11581
  if (type === "official") {
11823
- official[adderId] ?? (official[adderId] = {});
11824
- values = official[adderId];
11582
+ official[addonId] ?? (official[addonId] = {});
11583
+ values = official[addonId];
11825
11584
  }
11826
11585
  if (type === "community") {
11827
- community[adderId] ?? (community[adderId] = {});
11828
- values = community[adderId];
11586
+ community[addonId] ?? (community[addonId] = {});
11587
+ values = community[addonId];
11829
11588
  }
11830
- for (const [questionId, question] of Object.entries(adder.options)) {
11589
+ for (const [questionId, question] of Object.entries(addon.options)) {
11831
11590
  const shouldAsk = question.condition?.(values);
11832
11591
  if (shouldAsk === false || values[questionId] !== void 0) continue;
11833
11592
  let answer;
@@ -11868,17 +11627,29 @@ Available options: ${communityAdderIds.join(", ")}`
11868
11627
  values[questionId] = answer;
11869
11628
  }
11870
11629
  }
11871
- if (selectedAdders.length === 0) return { packageManager: null };
11630
+ if (selectedAddons.length === 0) return { packageManager: null };
11872
11631
  let packageManager;
11873
11632
  if (options.install) {
11874
11633
  packageManager = await packageManagerPrompt(options.cwd);
11634
+ if (packageManager) workspace.packageManager = packageManager;
11875
11635
  }
11876
- const filesToFormat = await runAdders({ cwd: options.cwd, packageManager, official, community });
11636
+ const officialDetails = Object.keys(official).map((id) => getAddonDetails(id));
11637
+ const commDetails = Object.keys(community).map(
11638
+ (id) => communityDetails.find((a) => a.id === id)
11639
+ );
11640
+ const details = officialDetails.concat(commDetails);
11641
+ const addonMap = Object.assign({}, ...details.map((a) => ({ [a.id]: a })));
11642
+ const filesToFormat = await applyAddons({
11643
+ workspace,
11644
+ addonSetupResults,
11645
+ addons: addonMap,
11646
+ options: official
11647
+ });
11877
11648
  log$1.success("Successfully setup add-ons");
11878
11649
  if (packageManager && options.install) {
11879
11650
  await installDependencies(packageManager, options.cwd);
11880
11651
  }
11881
- const workspace = createWorkspace({ cwd: options.cwd, packageManager });
11652
+ workspace = createWorkspace(workspace);
11882
11653
  if (filesToFormat.length > 0 && packageManager && !!workspace.dependencyVersion("prettier")) {
11883
11654
  const { start, stop } = spinner();
11884
11655
  start("Formatting modified files");
@@ -11891,92 +11662,39 @@ Available options: ${communityAdderIds.join(", ")}`
11891
11662
  }
11892
11663
  }
11893
11664
  const highlighter = getHighlighter();
11894
- const nextSteps = selectedAdders.filter(({ adder }) => adder.nextSteps).map(({ adder }) => {
11895
- let adderMessage = "";
11896
- if (selectedAdders.length > 1) {
11897
- adderMessage = `${pc.green(adder.id)}:
11665
+ const nextSteps = selectedAddons.filter(({ addon }) => addon.nextSteps).map(({ addon }) => {
11666
+ let addonMessage = "";
11667
+ if (selectedAddons.length > 1) {
11668
+ addonMessage = `${pc.green(addon.id)}:
11898
11669
  `;
11899
11670
  }
11900
- const adderNextSteps = adder.nextSteps({
11671
+ const addonNextSteps = addon.nextSteps({
11901
11672
  ...workspace,
11902
- options: official[adder.id],
11673
+ options: official[addon.id],
11903
11674
  highlighter
11904
11675
  });
11905
- adderMessage += `- ${adderNextSteps.join("\n- ")}`;
11906
- return adderMessage;
11676
+ addonMessage += `- ${addonNextSteps.join("\n- ")}`;
11677
+ return addonMessage;
11907
11678
  }).join("\n\n") || void 0;
11908
11679
  return { nextSteps, packageManager };
11909
11680
  }
11910
- async function runAdders({
11911
- cwd,
11912
- official = {},
11913
- community = {},
11914
- packageManager
11915
- }) {
11916
- const adderDetails = Object.keys(official).map((id) => getAdderDetails(id));
11917
- const commDetails = Object.keys(community).map(
11918
- (id) => communityDetails.find((a) => a.id === id)
11919
- );
11920
- const details = adderDetails.concat(commDetails);
11921
- details.sort((a, b) => {
11922
- if (!a.dependsOn && !b.dependsOn) return 0;
11923
- if (!a.dependsOn) return -1;
11924
- if (!b.dependsOn) return 1;
11925
- return a.dependsOn.includes(b.id) ? 1 : b.dependsOn.includes(a.id) ? -1 : 0;
11926
- });
11927
- const filesToFormat = /* @__PURE__ */ new Set();
11928
- for (const config of details) {
11929
- const adderId = config.id;
11930
- const workspace = createWorkspace({ cwd, packageManager });
11931
- workspace.options = official[adderId] ?? community[adderId];
11932
- await config.preInstall?.(workspace);
11933
- const pkgPath = installPackages(config, workspace);
11934
- filesToFormat.add(pkgPath);
11935
- const changedFiles = createOrUpdateFiles(config.files, workspace);
11936
- changedFiles.forEach((file) => filesToFormat.add(file));
11937
- await config.postInstall?.(workspace);
11938
- if (config.scripts && config.scripts.length > 0) {
11939
- for (const script of config.scripts) {
11940
- if (script.condition?.(workspace) === false) continue;
11941
- const { command, args } = resolveCommand(workspace.packageManager, "execute", script.args);
11942
- const adderPrefix = details.length > 1 ? `${config.id}: ` : "";
11943
- log$1.step(
11944
- `${adderPrefix}Running external command ${pc.gray(`(${command} ${args.join(" ")})`)}`
11945
- );
11946
- if (workspace.packageManager === "npm") args.unshift("--yes");
11947
- try {
11948
- await be(command, args, {
11949
- nodeOptions: { cwd: workspace.cwd, stdio: script.stdio },
11950
- throwOnError: true
11951
- });
11952
- } catch (error) {
11953
- const typedError = error;
11954
- throw new Error(
11955
- `Failed to execute scripts '${script.description}': ` + typedError.message
11956
- );
11957
- }
11958
- }
11959
- }
11960
- }
11961
- return Array.from(filesToFormat);
11962
- }
11963
11681
  function transformAliases(ids) {
11964
11682
  const set = /* @__PURE__ */ new Set();
11965
11683
  for (const id of ids) {
11966
11684
  if (aliases.includes(id)) {
11967
- const adder = officialAdders.find((a) => a.alias === id);
11968
- set.add(adder.id);
11685
+ const addon = officialAddons.find((a) => a.alias === id);
11686
+ set.add(addon.id);
11969
11687
  } else {
11970
11688
  set.add(id);
11971
11689
  }
11972
11690
  }
11973
11691
  return Array.from(set);
11974
11692
  }
11975
- function getAdderOptionFlags() {
11693
+ function getAddonOptionFlags() {
11976
11694
  const options = [];
11977
- for (const adder of officialAdders) {
11978
- const id = adder.id;
11979
- const details = getAdderDetails(id);
11695
+ for (const addon of officialAddons) {
11696
+ const id = addon.id;
11697
+ const details = getAddonDetails(id);
11980
11698
  if (Object.values(details.options).length === 0) continue;
11981
11699
  const { defaults, groups } = getOptionChoices(details);
11982
11700
  const choices = Object.entries(groups).map(([group, choices2]) => `${pc.dim(`${group}:`)} ${choices2.join(", ")}`).join("\n");
@@ -12030,10 +11748,6 @@ function getOptionChoices(details) {
12030
11748
  }
12031
11749
  return { choices, defaults, groups };
12032
11750
  }
12033
- function getPadding(lines) {
12034
- const lengths = lines.map((s) => s.length);
12035
- return Math.max(...lengths);
12036
- }
12037
11751
 
12038
11752
  const langs = ["ts", "jsdoc"];
12039
11753
  const langMap = {