sv 0.5.1 → 0.5.2
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 +765 -915
- package/dist/bin.js.map +1 -1
- package/dist/{index-CfDBZLMZ.js → index-A89HFWzv.js} +3 -3
- package/dist/index-A89HFWzv.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/shared.json +5 -5
- package/dist/templates/demo/meta.json +2 -2
- package/dist/templates/demo/package.json +2 -2
- package/dist/templates/library/meta.json +4 -0
- package/dist/templates/{skeletonlib → library}/package.json +6 -6
- package/dist/templates/minimal/meta.json +4 -0
- package/dist/templates/{skeleton → minimal}/package.json +2 -3
- package/dist/unocss-BUQS5wKg.js +6 -0
- package/dist/unocss-BUQS5wKg.js.map +1 -0
- package/dist/unplugin-icons-BietOpsP.js +6 -0
- package/dist/unplugin-icons-BietOpsP.js.map +1 -0
- package/package.json +17 -17
- package/dist/index-CfDBZLMZ.js.map +0 -1
- package/dist/templates/skeleton/meta.json +0 -4
- package/dist/templates/skeletonlib/meta.json +0 -4
- package/dist/unocss-Dk7i15rK.js +0 -11
- package/dist/unocss-Dk7i15rK.js.map +0 -1
- package/dist/unplugin-icons-DkNLYvBs.js +0 -11
- package/dist/unplugin-icons-DkNLYvBs.js.map +0 -1
- /package/dist/templates/{skeletonlib → library}/assets/DOT-gitignore +0 -0
- /package/dist/templates/{skeleton → library}/assets/DOT-npmrc +0 -0
- /package/dist/templates/{skeletonlib → library}/assets/src/app.html +0 -0
- /package/dist/templates/{skeleton → library}/assets/static/favicon.png +0 -0
- /package/dist/templates/{skeletonlib → library}/files.types=checkjs.json +0 -0
- /package/dist/templates/{skeletonlib → library}/files.types=none.json +0 -0
- /package/dist/templates/{skeletonlib → library}/files.types=typescript.json +0 -0
- /package/dist/templates/{skeleton → minimal}/assets/DOT-gitignore +0 -0
- /package/dist/templates/{skeletonlib → minimal}/assets/DOT-npmrc +0 -0
- /package/dist/templates/{skeleton → minimal}/assets/src/app.html +0 -0
- /package/dist/templates/{skeletonlib → minimal}/assets/static/favicon.png +0 -0
- /package/dist/templates/{skeleton → minimal}/files.types=checkjs.json +0 -0
- /package/dist/templates/{skeleton → minimal}/files.types=none.json +0 -0
- /package/dist/templates/{skeleton → minimal}/files.types=typescript.json +0 -0
package/dist/bin.js
CHANGED
|
@@ -22,28 +22,28 @@ import 'node:fs/promises';
|
|
|
22
22
|
import { pipeline as pipeline$1 } from 'node:stream/promises';
|
|
23
23
|
import { createGunzip } from 'node:zlib';
|
|
24
24
|
import require$$0$3 from 'events';
|
|
25
|
-
import { t as templates, c as create$2 } from './index-
|
|
25
|
+
import { t as templates, c as create$2 } from './index-A89HFWzv.js';
|
|
26
26
|
|
|
27
27
|
var name = "sv";
|
|
28
|
-
var version = "0.5.
|
|
28
|
+
var version = "0.5.2";
|
|
29
|
+
var type = "module";
|
|
29
30
|
var description = "A CLI for creating and updating SvelteKit projects";
|
|
30
|
-
var
|
|
31
|
-
"create",
|
|
32
|
-
"new",
|
|
33
|
-
"project",
|
|
34
|
-
"starter",
|
|
35
|
-
"svelte",
|
|
36
|
-
"sveltekit",
|
|
37
|
-
"template",
|
|
38
|
-
"wizard"
|
|
39
|
-
];
|
|
31
|
+
var license = "MIT";
|
|
40
32
|
var repository = {
|
|
41
33
|
type: "git",
|
|
42
34
|
url: "https://github.com/sveltejs/cli",
|
|
43
35
|
directory: "packages/cli"
|
|
44
36
|
};
|
|
45
|
-
var license = "MIT";
|
|
46
37
|
var homepage = "https://svelte.dev";
|
|
38
|
+
var scripts = {
|
|
39
|
+
check: "tsc",
|
|
40
|
+
format: "pnpm lint --write",
|
|
41
|
+
lint: "prettier --check . --config ../../prettier.config.js --ignore-path ../../.gitignore --ignore-path .gitignore --ignore-path ../../.prettierignore",
|
|
42
|
+
postpublish: "pnpm -F @sveltejs/create update-template-repo"
|
|
43
|
+
};
|
|
44
|
+
var files = [
|
|
45
|
+
"dist"
|
|
46
|
+
];
|
|
47
47
|
var bin = "./dist/bin.js";
|
|
48
48
|
var exports$1 = {
|
|
49
49
|
".": {
|
|
@@ -65,30 +65,30 @@ var devDependencies = {
|
|
|
65
65
|
tinyexec: "^0.3.0",
|
|
66
66
|
valibot: "^0.41.0"
|
|
67
67
|
};
|
|
68
|
-
var
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
"
|
|
68
|
+
var keywords = [
|
|
69
|
+
"create",
|
|
70
|
+
"new",
|
|
71
|
+
"project",
|
|
72
|
+
"starter",
|
|
73
|
+
"svelte",
|
|
74
|
+
"sveltekit",
|
|
75
|
+
"template",
|
|
76
|
+
"wizard"
|
|
76
77
|
];
|
|
77
|
-
var type = "module";
|
|
78
78
|
var pkg = {
|
|
79
79
|
name: name,
|
|
80
80
|
version: version,
|
|
81
|
+
type: type,
|
|
81
82
|
description: description,
|
|
82
|
-
keywords: keywords,
|
|
83
|
-
repository: repository,
|
|
84
83
|
license: license,
|
|
84
|
+
repository: repository,
|
|
85
85
|
homepage: homepage,
|
|
86
|
+
scripts: scripts,
|
|
87
|
+
files: files,
|
|
86
88
|
bin: bin,
|
|
87
89
|
exports: exports$1,
|
|
88
90
|
devDependencies: devDependencies,
|
|
89
|
-
|
|
90
|
-
files: files,
|
|
91
|
-
type: type
|
|
91
|
+
keywords: keywords
|
|
92
92
|
};
|
|
93
93
|
|
|
94
94
|
var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
@@ -5608,83 +5608,6 @@ class ConfirmPrompt extends Prompt {
|
|
|
5608
5608
|
});
|
|
5609
5609
|
}
|
|
5610
5610
|
}
|
|
5611
|
-
var __defProp$5 = Object.defineProperty;
|
|
5612
|
-
var __typeError = (msg) => {
|
|
5613
|
-
throw TypeError(msg);
|
|
5614
|
-
};
|
|
5615
|
-
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5616
|
-
var __publicField$5 = (obj, key, value) => __defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5617
|
-
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5618
|
-
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
5619
|
-
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
5620
|
-
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
5621
|
-
var _selectableGroups;
|
|
5622
|
-
class GroupMultiSelectPrompt extends Prompt {
|
|
5623
|
-
constructor(opts) {
|
|
5624
|
-
super(opts, false);
|
|
5625
|
-
__publicField$5(this, "options");
|
|
5626
|
-
__publicField$5(this, "cursor", 0);
|
|
5627
|
-
__privateAdd(this, _selectableGroups);
|
|
5628
|
-
const { options } = opts;
|
|
5629
|
-
__privateSet(this, _selectableGroups, opts.selectableGroups ?? true);
|
|
5630
|
-
this.options = Object.entries(options).flatMap(([key, option]) => [
|
|
5631
|
-
{ value: key, group: true, label: key },
|
|
5632
|
-
...option.map((opt) => ({ ...opt, group: key }))
|
|
5633
|
-
]);
|
|
5634
|
-
this.value = [...opts.initialValues ?? []];
|
|
5635
|
-
this.cursor = Math.max(
|
|
5636
|
-
this.options.findIndex(({ value }) => value === opts.cursorAt),
|
|
5637
|
-
__privateGet(this, _selectableGroups) ? 0 : 1
|
|
5638
|
-
);
|
|
5639
|
-
this.on("cursor", (key) => {
|
|
5640
|
-
switch (key) {
|
|
5641
|
-
case "left":
|
|
5642
|
-
case "up":
|
|
5643
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
5644
|
-
if (!__privateGet(this, _selectableGroups) && this.options[this.cursor].group === true) {
|
|
5645
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
5646
|
-
}
|
|
5647
|
-
break;
|
|
5648
|
-
case "down":
|
|
5649
|
-
case "right":
|
|
5650
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
5651
|
-
if (!__privateGet(this, _selectableGroups) && this.options[this.cursor].group === true) {
|
|
5652
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
5653
|
-
}
|
|
5654
|
-
break;
|
|
5655
|
-
case "space":
|
|
5656
|
-
this.toggleValue();
|
|
5657
|
-
break;
|
|
5658
|
-
}
|
|
5659
|
-
});
|
|
5660
|
-
}
|
|
5661
|
-
getGroupItems(group2) {
|
|
5662
|
-
return this.options.filter((o) => o.group === group2);
|
|
5663
|
-
}
|
|
5664
|
-
isGroupSelected(group2) {
|
|
5665
|
-
const items = this.getGroupItems(group2);
|
|
5666
|
-
return __privateGet(this, _selectableGroups) && items.every((i) => this.value.includes(i.value));
|
|
5667
|
-
}
|
|
5668
|
-
toggleValue() {
|
|
5669
|
-
const item = this.options[this.cursor];
|
|
5670
|
-
if (item.group === true) {
|
|
5671
|
-
const group2 = item.value;
|
|
5672
|
-
const groupedItems = this.getGroupItems(group2);
|
|
5673
|
-
if (this.isGroupSelected(group2)) {
|
|
5674
|
-
this.value = this.value.filter(
|
|
5675
|
-
(v) => groupedItems.findIndex((i) => i.value === v) === -1
|
|
5676
|
-
);
|
|
5677
|
-
} else {
|
|
5678
|
-
this.value = [...this.value, ...groupedItems.map((i) => i.value)];
|
|
5679
|
-
}
|
|
5680
|
-
this.value = Array.from(new Set(this.value));
|
|
5681
|
-
} else {
|
|
5682
|
-
const selected = this.value.includes(item.value);
|
|
5683
|
-
this.value = selected ? this.value.filter((v) => v !== item.value) : [...this.value, item.value];
|
|
5684
|
-
}
|
|
5685
|
-
}
|
|
5686
|
-
}
|
|
5687
|
-
_selectableGroups = /* @__PURE__ */ new WeakMap();
|
|
5688
5611
|
var __defProp$4 = Object.defineProperty;
|
|
5689
5612
|
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5690
5613
|
var __publicField$4 = (obj, key, value) => __defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -6277,112 +6200,6 @@ ${color$2.cyan(S_BAR_END)}
|
|
|
6277
6200
|
}
|
|
6278
6201
|
}).prompt();
|
|
6279
6202
|
};
|
|
6280
|
-
const groupMultiselect = (opts) => {
|
|
6281
|
-
const { selectableGroups = false, spacedGroups = false } = opts;
|
|
6282
|
-
const opt = (option, state, options = []) => {
|
|
6283
|
-
const label = option.label ?? String(option.value);
|
|
6284
|
-
const isItem = typeof option.group === "string";
|
|
6285
|
-
const next = isItem && (options[options.indexOf(option) + 1] ?? { group: true });
|
|
6286
|
-
const isLast = isItem && next.group === true;
|
|
6287
|
-
const prefix = isItem ? selectableGroups ? `${isLast ? S_BAR_END : S_BAR$1} ` : " " : "";
|
|
6288
|
-
const spacingPrefix = spacedGroups && !isItem ? `
|
|
6289
|
-
${color$2.cyan(S_BAR$1)} ` : "";
|
|
6290
|
-
if (state === "active") {
|
|
6291
|
-
return `${spacingPrefix}${color$2.dim(prefix)}${color$2.cyan(S_CHECKBOX_ACTIVE)} ${label} ${option.hint ? color$2.dim(`(${option.hint})`) : ""}`;
|
|
6292
|
-
} else if (state === "group-active") {
|
|
6293
|
-
return `${spacingPrefix}${prefix}${color$2.cyan(S_CHECKBOX_ACTIVE)} ${color$2.dim(label)}`;
|
|
6294
|
-
} else if (state === "group-active-selected") {
|
|
6295
|
-
return `${spacingPrefix}${prefix}${color$2.green(S_CHECKBOX_SELECTED)} ${color$2.dim(label)}`;
|
|
6296
|
-
} else if (state === "selected") {
|
|
6297
|
-
return `${spacingPrefix}${color$2.dim(prefix)}${color$2.green(S_CHECKBOX_SELECTED)} ${color$2.dim(
|
|
6298
|
-
label
|
|
6299
|
-
)}`;
|
|
6300
|
-
} else if (state === "cancelled") {
|
|
6301
|
-
return color$2.strikethrough(color$2.dim(label));
|
|
6302
|
-
} else if (state === "active-selected") {
|
|
6303
|
-
return `${spacingPrefix}${color$2.dim(prefix)}${color$2.green(S_CHECKBOX_SELECTED)} ${label} ${option.hint ? color$2.dim(`(${option.hint})`) : ""}`;
|
|
6304
|
-
} else if (state === "submitted") {
|
|
6305
|
-
return color$2.dim(label);
|
|
6306
|
-
}
|
|
6307
|
-
return `${spacingPrefix}${color$2.dim(prefix)}${isItem || selectableGroups ? `${color$2.dim(S_CHECKBOX_INACTIVE)} ` : ""}${color$2.dim(label)}`;
|
|
6308
|
-
};
|
|
6309
|
-
return new GroupMultiSelectPrompt({
|
|
6310
|
-
options: opts.options,
|
|
6311
|
-
initialValues: opts.initialValues,
|
|
6312
|
-
required: opts.required ?? true,
|
|
6313
|
-
cursorAt: opts.cursorAt,
|
|
6314
|
-
selectableGroups,
|
|
6315
|
-
validate(selected) {
|
|
6316
|
-
if (this.required && selected.length === 0)
|
|
6317
|
-
return `Please select at least one option.
|
|
6318
|
-
${color$2.reset(
|
|
6319
|
-
color$2.dim(
|
|
6320
|
-
`Press ${color$2.gray(color$2.bgWhite(color$2.inverse(" space ")))} to select, ${color$2.gray(
|
|
6321
|
-
color$2.bgWhite(color$2.inverse(" enter "))
|
|
6322
|
-
)} to submit`
|
|
6323
|
-
)
|
|
6324
|
-
)}`;
|
|
6325
|
-
},
|
|
6326
|
-
render() {
|
|
6327
|
-
const title = `${color$2.gray(S_BAR$1)}
|
|
6328
|
-
${symbol(this.state)} ${opts.message}
|
|
6329
|
-
`;
|
|
6330
|
-
switch (this.state) {
|
|
6331
|
-
case "submit": {
|
|
6332
|
-
return `${title}${color$2.gray(S_BAR$1)} ${this.options.filter(({ value }) => this.value.includes(value)).map((option) => opt(option, "submitted")).join(color$2.dim(", "))}`;
|
|
6333
|
-
}
|
|
6334
|
-
case "cancel": {
|
|
6335
|
-
const label = this.options.filter(({ value }) => this.value.includes(value)).map((option) => opt(option, "cancelled")).join(color$2.dim(", "));
|
|
6336
|
-
return `${title}${color$2.gray(S_BAR$1)} ${label.trim() ? `${label}
|
|
6337
|
-
${color$2.gray(S_BAR$1)}` : ""}`;
|
|
6338
|
-
}
|
|
6339
|
-
case "error": {
|
|
6340
|
-
const footer = this.error.split("\n").map(
|
|
6341
|
-
(ln, i) => i === 0 ? `${color$2.yellow(S_BAR_END)} ${color$2.yellow(ln)}` : ` ${ln}`
|
|
6342
|
-
).join("\n");
|
|
6343
|
-
return `${title}${color$2.yellow(S_BAR$1)} ${this.options.map((option, i, options) => {
|
|
6344
|
-
const selected = this.value.includes(option.value) || option.group === true && this.isGroupSelected(`${option.value}`);
|
|
6345
|
-
const active = i === this.cursor;
|
|
6346
|
-
const groupActive = !active && typeof option.group === "string" && this.options[this.cursor].value === option.group;
|
|
6347
|
-
if (groupActive) {
|
|
6348
|
-
return opt(option, selected ? "group-active-selected" : "group-active", options);
|
|
6349
|
-
}
|
|
6350
|
-
if (active && selected) {
|
|
6351
|
-
return opt(option, "active-selected", options);
|
|
6352
|
-
}
|
|
6353
|
-
if (selected) {
|
|
6354
|
-
return opt(option, "selected", options);
|
|
6355
|
-
}
|
|
6356
|
-
return opt(option, active ? "active" : "inactive", options);
|
|
6357
|
-
}).join(`
|
|
6358
|
-
${color$2.yellow(S_BAR$1)} `)}
|
|
6359
|
-
${footer}
|
|
6360
|
-
`;
|
|
6361
|
-
}
|
|
6362
|
-
default: {
|
|
6363
|
-
return `${title}${color$2.cyan(S_BAR$1)} ${this.options.map((option, i, options) => {
|
|
6364
|
-
const selected = this.value.includes(option.value) || option.group === true && this.isGroupSelected(`${option.value}`);
|
|
6365
|
-
const active = i === this.cursor;
|
|
6366
|
-
const groupActive = !active && typeof option.group === "string" && this.options[this.cursor].value === option.group;
|
|
6367
|
-
if (groupActive) {
|
|
6368
|
-
return opt(option, selected ? "group-active-selected" : "group-active", options);
|
|
6369
|
-
}
|
|
6370
|
-
if (active && selected) {
|
|
6371
|
-
return opt(option, "active-selected", options);
|
|
6372
|
-
}
|
|
6373
|
-
if (selected) {
|
|
6374
|
-
return opt(option, "selected", options);
|
|
6375
|
-
}
|
|
6376
|
-
return opt(option, active ? "active" : "inactive", options);
|
|
6377
|
-
}).join(`
|
|
6378
|
-
${color$2.cyan(S_BAR$1)} `)}
|
|
6379
|
-
${color$2.cyan(S_BAR_END)}
|
|
6380
|
-
`;
|
|
6381
|
-
}
|
|
6382
|
-
}
|
|
6383
|
-
}
|
|
6384
|
-
}).prompt();
|
|
6385
|
-
};
|
|
6386
6203
|
const strip$1 = (str) => str.replace(ansiRegex(), "");
|
|
6387
6204
|
function buildBox(message = "", title = "", dimmed = true) {
|
|
6388
6205
|
const lines = `
|
|
@@ -45856,8 +45673,15 @@ function parseScript$1(content) {
|
|
|
45856
45673
|
});
|
|
45857
45674
|
return recastOutput.program;
|
|
45858
45675
|
}
|
|
45859
|
-
function serializeScript(ast) {
|
|
45860
|
-
|
|
45676
|
+
function serializeScript(ast, previousContent) {
|
|
45677
|
+
let options2;
|
|
45678
|
+
if (!previousContent) {
|
|
45679
|
+
options2 = {
|
|
45680
|
+
quote: "single",
|
|
45681
|
+
useTabs: true
|
|
45682
|
+
};
|
|
45683
|
+
}
|
|
45684
|
+
return main.print(ast, options2).code;
|
|
45861
45685
|
}
|
|
45862
45686
|
function parseCss$1(content) {
|
|
45863
45687
|
return parse$1(content);
|
|
@@ -46345,6 +46169,19 @@ function addEmpty(ast, importFrom) {
|
|
|
46345
46169
|
};
|
|
46346
46170
|
addImportIfNecessary(ast, expectedImportDeclaration);
|
|
46347
46171
|
}
|
|
46172
|
+
function addNamespace(ast, importFrom, importAs) {
|
|
46173
|
+
const expectedImportDeclaration = {
|
|
46174
|
+
type: "ImportDeclaration",
|
|
46175
|
+
source: { type: "Literal", value: importFrom },
|
|
46176
|
+
specifiers: [
|
|
46177
|
+
{
|
|
46178
|
+
type: "ImportNamespaceSpecifier",
|
|
46179
|
+
local: { type: "Identifier", name: importAs }
|
|
46180
|
+
}
|
|
46181
|
+
]
|
|
46182
|
+
};
|
|
46183
|
+
addImportIfNecessary(ast, expectedImportDeclaration);
|
|
46184
|
+
}
|
|
46348
46185
|
function addDefault(ast, importFrom, importAs) {
|
|
46349
46186
|
const expectedImportDeclaration = {
|
|
46350
46187
|
type: "ImportDeclaration",
|
|
@@ -46421,7 +46258,8 @@ var imports = /* @__PURE__ */ Object.freeze({
|
|
|
46421
46258
|
__proto__: null,
|
|
46422
46259
|
addDefault,
|
|
46423
46260
|
addEmpty,
|
|
46424
|
-
addNamed
|
|
46261
|
+
addNamed,
|
|
46262
|
+
addNamespace
|
|
46425
46263
|
});
|
|
46426
46264
|
function declaration(ast, kind, name, value) {
|
|
46427
46265
|
const declarations = ast.type == "Program" ? ast.body.filter((x) => x.type == "VariableDeclaration") : [ast];
|
|
@@ -48310,7 +48148,7 @@ let MagicString$1 = class MagicString {
|
|
|
48310
48148
|
};
|
|
48311
48149
|
function parseScript(source) {
|
|
48312
48150
|
const ast = parseScript$1(source);
|
|
48313
|
-
const generateCode = () => serializeScript(ast);
|
|
48151
|
+
const generateCode = () => serializeScript(ast, source);
|
|
48314
48152
|
return { ast, source, generateCode };
|
|
48315
48153
|
}
|
|
48316
48154
|
function parseCss(source) {
|
|
@@ -48494,10 +48332,8 @@ const options$3 = defineAdderOptions({
|
|
|
48494
48332
|
});
|
|
48495
48333
|
var drizzle = defineAdder({
|
|
48496
48334
|
id: "drizzle",
|
|
48497
|
-
name: "Drizzle",
|
|
48498
|
-
description: "Headless ORM for NodeJS, TypeScript and JavaScript",
|
|
48499
48335
|
environments: { svelte: false, kit: true },
|
|
48500
|
-
|
|
48336
|
+
homepage: "https://orm.drizzle.team",
|
|
48501
48337
|
options: options$3,
|
|
48502
48338
|
packages: [
|
|
48503
48339
|
{ name: "drizzle-orm", version: "^0.33.0", dev: false },
|
|
@@ -48769,7 +48605,7 @@ var drizzle = defineAdder({
|
|
|
48769
48605
|
if (options2.docker) {
|
|
48770
48606
|
steps.push(`Run ${highlighter.command("npm run db:start")} to start the docker container`);
|
|
48771
48607
|
}
|
|
48772
|
-
steps.push(`
|
|
48608
|
+
steps.push(`Run ${highlighter.command("npm run db:push")} to update your database schema`);
|
|
48773
48609
|
return steps;
|
|
48774
48610
|
}
|
|
48775
48611
|
});
|
|
@@ -48865,10 +48701,8 @@ function addEslintConfigPrettier({ content }) {
|
|
|
48865
48701
|
|
|
48866
48702
|
var eslint = defineAdder({
|
|
48867
48703
|
id: "eslint",
|
|
48868
|
-
name: "ESLint",
|
|
48869
|
-
description: "A configurable JavaScript linter",
|
|
48870
48704
|
environments: { svelte: true, kit: true },
|
|
48871
|
-
|
|
48705
|
+
homepage: "https://eslint.org",
|
|
48872
48706
|
options: {},
|
|
48873
48707
|
packages: [
|
|
48874
48708
|
{ name: "eslint", version: "^9.7.0", dev: true },
|
|
@@ -48986,570 +48820,6 @@ var eslint = defineAdder({
|
|
|
48986
48820
|
]
|
|
48987
48821
|
});
|
|
48988
48822
|
|
|
48989
|
-
var __freeze = Object.freeze;
|
|
48990
|
-
var __defProp = Object.defineProperty;
|
|
48991
|
-
var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(cooked.slice()) }));
|
|
48992
|
-
var _a, _b;
|
|
48993
|
-
const LUCIA_ADAPTER = {
|
|
48994
|
-
mysql: "DrizzleMySQLAdapter",
|
|
48995
|
-
postgresql: "DrizzlePostgreSQLAdapter",
|
|
48996
|
-
sqlite: "DrizzleSQLiteAdapter"
|
|
48997
|
-
};
|
|
48998
|
-
const TABLE_TYPE = {
|
|
48999
|
-
mysql: "mysqlTable",
|
|
49000
|
-
postgresql: "pgTable",
|
|
49001
|
-
sqlite: "sqliteTable"
|
|
49002
|
-
};
|
|
49003
|
-
let drizzleDialect;
|
|
49004
|
-
let schemaPath;
|
|
49005
|
-
const options$2 = defineAdderOptions({
|
|
49006
|
-
demo: {
|
|
49007
|
-
type: "boolean",
|
|
49008
|
-
default: false,
|
|
49009
|
-
question: `Do you want to include a demo? ${picocolors.dim("(includes a login/register page)")}`
|
|
49010
|
-
}
|
|
49011
|
-
});
|
|
49012
|
-
var lucia = defineAdder({
|
|
49013
|
-
id: "lucia",
|
|
49014
|
-
name: "Lucia",
|
|
49015
|
-
description: "An auth library that abstracts away the complexity of handling sessions",
|
|
49016
|
-
environments: { svelte: false, kit: true },
|
|
49017
|
-
documentation: "https://lucia-auth.com",
|
|
49018
|
-
options: options$2,
|
|
49019
|
-
packages: [
|
|
49020
|
-
{ name: "lucia", version: "^3.2.0", dev: false },
|
|
49021
|
-
{ name: "@lucia-auth/adapter-drizzle", version: "^1.1.0", dev: false },
|
|
49022
|
-
// password hashing for demo
|
|
49023
|
-
{
|
|
49024
|
-
name: "@node-rs/argon2",
|
|
49025
|
-
version: "^1.1.0",
|
|
49026
|
-
condition: ({ options: options2 }) => options2.demo,
|
|
49027
|
-
dev: false
|
|
49028
|
-
}
|
|
49029
|
-
],
|
|
49030
|
-
dependsOn: ["drizzle"],
|
|
49031
|
-
files: [
|
|
49032
|
-
{
|
|
49033
|
-
name: ({ typescript }) => `drizzle.config.${typescript ? "ts" : "js"}`,
|
|
49034
|
-
content: ({ content }) => {
|
|
49035
|
-
const { ast, generateCode } = parseScript(content);
|
|
49036
|
-
const isProp = (name, node) => node.key.type === "Identifier" && node.key.name === name;
|
|
49037
|
-
walk$1.walk(ast, {}, {
|
|
49038
|
-
ObjectProperty(node) {
|
|
49039
|
-
if (isProp("dialect", node) && node.value.type === "StringLiteral") {
|
|
49040
|
-
drizzleDialect = node.value.value;
|
|
49041
|
-
}
|
|
49042
|
-
if (isProp("schema", node) && node.value.type === "StringLiteral") {
|
|
49043
|
-
schemaPath = node.value.value;
|
|
49044
|
-
}
|
|
49045
|
-
}
|
|
49046
|
-
});
|
|
49047
|
-
if (!drizzleDialect) {
|
|
49048
|
-
throw new Error("Failed to detect DB dialect in your `drizzle.config.[js|ts]` file");
|
|
49049
|
-
}
|
|
49050
|
-
if (!schemaPath) {
|
|
49051
|
-
throw new Error("Failed to find schema path in your `drizzle.config.[js|ts]` file");
|
|
49052
|
-
}
|
|
49053
|
-
return generateCode();
|
|
49054
|
-
}
|
|
49055
|
-
},
|
|
49056
|
-
{
|
|
49057
|
-
name: () => schemaPath,
|
|
49058
|
-
content: ({ content, options: options2 }) => {
|
|
49059
|
-
const { ast, generateCode } = parseScript(content);
|
|
49060
|
-
const createTable = (name) => _function.call(TABLE_TYPE[drizzleDialect], [name]);
|
|
49061
|
-
const userDecl = variables.declaration(ast, "const", "user", createTable("user"));
|
|
49062
|
-
const sessionDecl = variables.declaration(ast, "const", "session", createTable("session"));
|
|
49063
|
-
const user = exports.namedExport(ast, "user", userDecl);
|
|
49064
|
-
const session = exports.namedExport(ast, "session", sessionDecl);
|
|
49065
|
-
const userTable = getCallExpression(user);
|
|
49066
|
-
const sessionTable = getCallExpression(session);
|
|
49067
|
-
if (!userTable || !sessionTable) {
|
|
49068
|
-
throw new Error("failed to find call expression of `user` or `session`");
|
|
49069
|
-
}
|
|
49070
|
-
if (userTable.arguments.length === 1) {
|
|
49071
|
-
userTable.arguments.push(object.createEmpty());
|
|
49072
|
-
}
|
|
49073
|
-
if (sessionTable.arguments.length === 1) {
|
|
49074
|
-
sessionTable.arguments.push(object.createEmpty());
|
|
49075
|
-
}
|
|
49076
|
-
const userAttributes = userTable.arguments[1];
|
|
49077
|
-
const sessionAttributes = sessionTable.arguments[1];
|
|
49078
|
-
if (userAttributes?.type !== "ObjectExpression" || sessionAttributes?.type !== "ObjectExpression") {
|
|
49079
|
-
throw new Error("unexpected shape of `user` or `session` table definition");
|
|
49080
|
-
}
|
|
49081
|
-
if (drizzleDialect === "sqlite") {
|
|
49082
|
-
imports.addNamed(ast, "drizzle-orm/sqlite-core", {
|
|
49083
|
-
sqliteTable: "sqliteTable",
|
|
49084
|
-
text: "text",
|
|
49085
|
-
integer: "integer"
|
|
49086
|
-
});
|
|
49087
|
-
object.overrideProperties(userAttributes, {
|
|
49088
|
-
id: common.expressionFromString(`text('id').primaryKey()`)
|
|
49089
|
-
});
|
|
49090
|
-
if (options2.demo) {
|
|
49091
|
-
object.overrideProperties(userAttributes, {
|
|
49092
|
-
username: common.expressionFromString(`text('username').notNull().unique()`),
|
|
49093
|
-
passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
|
|
49094
|
-
});
|
|
49095
|
-
}
|
|
49096
|
-
object.overrideProperties(sessionAttributes, {
|
|
49097
|
-
id: common.expressionFromString(`text('id').primaryKey()`),
|
|
49098
|
-
userId: common.expressionFromString(
|
|
49099
|
-
`text('user_id').notNull().references(() => user.id)`
|
|
49100
|
-
),
|
|
49101
|
-
expiresAt: common.expressionFromString(`integer('expires_at').notNull()`)
|
|
49102
|
-
});
|
|
49103
|
-
}
|
|
49104
|
-
if (drizzleDialect === "mysql") {
|
|
49105
|
-
imports.addNamed(ast, "drizzle-orm/mysql-core", {
|
|
49106
|
-
mysqlTable: "mysqlTable",
|
|
49107
|
-
varchar: "varchar",
|
|
49108
|
-
datetime: "datetime"
|
|
49109
|
-
});
|
|
49110
|
-
object.overrideProperties(userAttributes, {
|
|
49111
|
-
id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`)
|
|
49112
|
-
});
|
|
49113
|
-
if (options2.demo) {
|
|
49114
|
-
object.overrideProperties(userAttributes, {
|
|
49115
|
-
username: common.expressionFromString(
|
|
49116
|
-
`varchar('username', { length: 32 }).notNull().unique()`
|
|
49117
|
-
),
|
|
49118
|
-
passwordHash: common.expressionFromString(
|
|
49119
|
-
`varchar('password_hash', { length: 255 }).notNull()`
|
|
49120
|
-
)
|
|
49121
|
-
});
|
|
49122
|
-
}
|
|
49123
|
-
object.overrideProperties(sessionAttributes, {
|
|
49124
|
-
id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`),
|
|
49125
|
-
userId: common.expressionFromString(
|
|
49126
|
-
`varchar('user_id', { length: 255 }).notNull().references(() => user.id)`
|
|
49127
|
-
),
|
|
49128
|
-
expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`)
|
|
49129
|
-
});
|
|
49130
|
-
}
|
|
49131
|
-
if (drizzleDialect === "postgresql") {
|
|
49132
|
-
imports.addNamed(ast, "drizzle-orm/pg-core", {
|
|
49133
|
-
pgTable: "pgTable",
|
|
49134
|
-
text: "text",
|
|
49135
|
-
timestamp: "timestamp"
|
|
49136
|
-
});
|
|
49137
|
-
object.overrideProperties(userAttributes, {
|
|
49138
|
-
id: common.expressionFromString(`text('id').primaryKey()`)
|
|
49139
|
-
});
|
|
49140
|
-
if (options2.demo) {
|
|
49141
|
-
object.overrideProperties(userAttributes, {
|
|
49142
|
-
username: common.expressionFromString(`text('username').notNull().unique()`),
|
|
49143
|
-
passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
|
|
49144
|
-
});
|
|
49145
|
-
}
|
|
49146
|
-
object.overrideProperties(sessionAttributes, {
|
|
49147
|
-
id: common.expressionFromString(`text('id').primaryKey()`),
|
|
49148
|
-
userId: common.expressionFromString(
|
|
49149
|
-
`text('user_id').notNull().references(() => user.id)`
|
|
49150
|
-
),
|
|
49151
|
-
expiresAt: common.expressionFromString(
|
|
49152
|
-
`timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()`
|
|
49153
|
-
)
|
|
49154
|
-
});
|
|
49155
|
-
}
|
|
49156
|
-
return generateCode();
|
|
49157
|
-
}
|
|
49158
|
-
},
|
|
49159
|
-
{
|
|
49160
|
-
name: ({ kit: kit2, typescript }) => `${kit2?.libDirectory}/server/auth.${typescript ? "ts" : "js"}`,
|
|
49161
|
-
content: ({ content, typescript, options: options2 }) => {
|
|
49162
|
-
const { ast, generateCode } = parseScript(content);
|
|
49163
|
-
const adapter = LUCIA_ADAPTER[drizzleDialect];
|
|
49164
|
-
imports.addNamed(ast, "$lib/server/db/schema.js", { user: "user", session: "session" });
|
|
49165
|
-
imports.addNamed(ast, "$lib/server/db", { db: "db" });
|
|
49166
|
-
imports.addNamed(ast, "lucia", { Lucia: "Lucia" });
|
|
49167
|
-
imports.addNamed(ast, "@lucia-auth/adapter-drizzle", { [adapter]: adapter });
|
|
49168
|
-
imports.addNamed(ast, "$app/environment", { dev: "dev" });
|
|
49169
|
-
const adapterDecl = common.statementFromString(
|
|
49170
|
-
`const adapter = new ${adapter}(db, session, user);`
|
|
49171
|
-
);
|
|
49172
|
-
common.addStatement(ast, adapterDecl);
|
|
49173
|
-
const luciaInit = common.expressionFromString(`
|
|
49174
|
-
new Lucia(adapter, {
|
|
49175
|
-
sessionCookie: {
|
|
49176
|
-
attributes: {
|
|
49177
|
-
secure: !dev
|
|
49178
|
-
}
|
|
49179
|
-
},
|
|
49180
|
-
${options2.demo ? "getUserAttributes: (attributes) => ({ username: attributes.username })" : ""}
|
|
49181
|
-
})`);
|
|
49182
|
-
const luciaDecl = variables.declaration(ast, "const", "lucia", luciaInit);
|
|
49183
|
-
exports.namedExport(ast, "lucia", luciaDecl);
|
|
49184
|
-
if (typescript && !/declare module ["']lucia["']/.test(content)) {
|
|
49185
|
-
const moduleDecl = common.statementFromString(`
|
|
49186
|
-
declare module 'lucia' {
|
|
49187
|
-
interface Register {
|
|
49188
|
-
Lucia: typeof lucia;
|
|
49189
|
-
// attributes that are already included are omitted
|
|
49190
|
-
DatabaseUserAttributes: Omit<typeof user.$inferSelect, 'id'>;
|
|
49191
|
-
DatabaseSessionAttributes: Omit<typeof session.$inferSelect, 'id' | 'userId' | 'expiresAt'>;
|
|
49192
|
-
}
|
|
49193
|
-
}`);
|
|
49194
|
-
common.addStatement(ast, moduleDecl);
|
|
49195
|
-
}
|
|
49196
|
-
return generateCode();
|
|
49197
|
-
}
|
|
49198
|
-
},
|
|
49199
|
-
{
|
|
49200
|
-
name: () => "src/app.d.ts",
|
|
49201
|
-
condition: ({ typescript }) => typescript,
|
|
49202
|
-
content: ({ content }) => {
|
|
49203
|
-
const { ast, generateCode } = parseScript(content);
|
|
49204
|
-
const locals = kit.addGlobalAppInterface(ast, "Locals");
|
|
49205
|
-
if (!locals) {
|
|
49206
|
-
throw new Error("Failed detecting `locals` interface in `src/app.d.ts`");
|
|
49207
|
-
}
|
|
49208
|
-
const user = locals.body.body.find((prop) => common.hasTypeProp("user", prop));
|
|
49209
|
-
const session = locals.body.body.find((prop) => common.hasTypeProp("session", prop));
|
|
49210
|
-
if (!user) {
|
|
49211
|
-
locals.body.body.push(createLuciaType("user"));
|
|
49212
|
-
}
|
|
49213
|
-
if (!session) {
|
|
49214
|
-
locals.body.body.push(createLuciaType("session"));
|
|
49215
|
-
}
|
|
49216
|
-
return generateCode();
|
|
49217
|
-
}
|
|
49218
|
-
},
|
|
49219
|
-
{
|
|
49220
|
-
name: ({ typescript }) => `src/hooks.server.${typescript ? "ts" : "js"}`,
|
|
49221
|
-
content: ({ content, typescript }) => {
|
|
49222
|
-
const { ast, generateCode } = parseScript(content);
|
|
49223
|
-
imports.addNamed(ast, "$lib/server/auth.js", { lucia: "lucia" });
|
|
49224
|
-
kit.addHooksHandle(ast, typescript, "auth", getAuthHandleContent());
|
|
49225
|
-
return generateCode();
|
|
49226
|
-
}
|
|
49227
|
-
},
|
|
49228
|
-
// DEMO
|
|
49229
|
-
// login/register
|
|
49230
|
-
{
|
|
49231
|
-
name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/login/+page.server.${typescript ? "ts" : "js"}`,
|
|
49232
|
-
condition: ({ options: options2 }) => options2.demo,
|
|
49233
|
-
content({ content, typescript }) {
|
|
49234
|
-
if (content) {
|
|
49235
|
-
log.warn(
|
|
49236
|
-
`Existing ${picocolors.yellow("/demo/login/+page.server.[js|ts]")} file. Could not update.`
|
|
49237
|
-
);
|
|
49238
|
-
return content;
|
|
49239
|
-
}
|
|
49240
|
-
const [ts] = utils.createPrinter(typescript);
|
|
49241
|
-
return dedent`
|
|
49242
|
-
import { fail, redirect } from '@sveltejs/kit';
|
|
49243
|
-
import { hash, verify } from '@node-rs/argon2';
|
|
49244
|
-
import { eq } from 'drizzle-orm';
|
|
49245
|
-
import { generateId } from 'lucia';
|
|
49246
|
-
import { lucia } from '$lib/server/auth';
|
|
49247
|
-
import { db } from '$lib/server/db';
|
|
49248
|
-
import { user } from '$lib/server/db/schema.js';
|
|
49249
|
-
${ts(`import type { Actions, PageServerLoad } from './$types';`)}
|
|
49250
|
-
|
|
49251
|
-
export const load${ts(": PageServerLoad")} = async (event) => {
|
|
49252
|
-
if (event.locals.user) {
|
|
49253
|
-
return redirect(302, '/demo');
|
|
49254
|
-
}
|
|
49255
|
-
return {};
|
|
49256
|
-
};
|
|
49257
|
-
|
|
49258
|
-
export const actions${ts(": Actions")} = {
|
|
49259
|
-
login: async (event) => {
|
|
49260
|
-
const formData = await event.request.formData();
|
|
49261
|
-
const username = formData.get('username');
|
|
49262
|
-
const password = formData.get('password');
|
|
49263
|
-
|
|
49264
|
-
if (!validateUsername(username)) {
|
|
49265
|
-
return fail(400, {
|
|
49266
|
-
message: 'Invalid username',
|
|
49267
|
-
});
|
|
49268
|
-
}
|
|
49269
|
-
if (!validatePassword(password)) {
|
|
49270
|
-
return fail(400, {
|
|
49271
|
-
message: 'Invalid password',
|
|
49272
|
-
});
|
|
49273
|
-
}
|
|
49274
|
-
|
|
49275
|
-
const results = await db
|
|
49276
|
-
.select()
|
|
49277
|
-
.from(user)
|
|
49278
|
-
.where(eq(user.username, username));
|
|
49279
|
-
|
|
49280
|
-
const existingUser = results.at(0);
|
|
49281
|
-
if (!existingUser) {
|
|
49282
|
-
return fail(400, {
|
|
49283
|
-
message: 'Incorrect username or password',
|
|
49284
|
-
});
|
|
49285
|
-
}
|
|
49286
|
-
|
|
49287
|
-
const validPassword = await verify(existingUser.passwordHash, password, {
|
|
49288
|
-
memoryCost: 19456,
|
|
49289
|
-
timeCost: 2,
|
|
49290
|
-
outputLen: 32,
|
|
49291
|
-
parallelism: 1,
|
|
49292
|
-
});
|
|
49293
|
-
if (!validPassword) {
|
|
49294
|
-
return fail(400, {
|
|
49295
|
-
message: 'Incorrect username or password',
|
|
49296
|
-
});
|
|
49297
|
-
}
|
|
49298
|
-
|
|
49299
|
-
const session = await lucia.createSession(existingUser.id, {});
|
|
49300
|
-
const sessionCookie = lucia.createSessionCookie(session.id);
|
|
49301
|
-
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
49302
|
-
path: '/',
|
|
49303
|
-
...sessionCookie.attributes,
|
|
49304
|
-
});
|
|
49305
|
-
|
|
49306
|
-
return redirect(302, '/demo');
|
|
49307
|
-
},
|
|
49308
|
-
register: async (event) => {
|
|
49309
|
-
const formData = await event.request.formData();
|
|
49310
|
-
const username = formData.get('username');
|
|
49311
|
-
const password = formData.get('password');
|
|
49312
|
-
|
|
49313
|
-
if (!validateUsername(username)) {
|
|
49314
|
-
return fail(400, {
|
|
49315
|
-
message: 'Invalid username',
|
|
49316
|
-
});
|
|
49317
|
-
}
|
|
49318
|
-
if (!validatePassword(password)) {
|
|
49319
|
-
return fail(400, {
|
|
49320
|
-
message: 'Invalid password',
|
|
49321
|
-
});
|
|
49322
|
-
}
|
|
49323
|
-
|
|
49324
|
-
const passwordHash = await hash(password, {
|
|
49325
|
-
// recommended minimum parameters
|
|
49326
|
-
memoryCost: 19456,
|
|
49327
|
-
timeCost: 2,
|
|
49328
|
-
outputLen: 32,
|
|
49329
|
-
parallelism: 1,
|
|
49330
|
-
});
|
|
49331
|
-
const userId = generateId(15);
|
|
49332
|
-
|
|
49333
|
-
try {
|
|
49334
|
-
await db.insert(user).values({
|
|
49335
|
-
id: userId,
|
|
49336
|
-
username,
|
|
49337
|
-
passwordHash,
|
|
49338
|
-
});
|
|
49339
|
-
|
|
49340
|
-
const session = await lucia.createSession(userId, {});
|
|
49341
|
-
const sessionCookie = lucia.createSessionCookie(session.id);
|
|
49342
|
-
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
49343
|
-
path: '/',
|
|
49344
|
-
...sessionCookie.attributes,
|
|
49345
|
-
});
|
|
49346
|
-
} catch (e) {
|
|
49347
|
-
return fail(500, {
|
|
49348
|
-
message: 'An error has occurred',
|
|
49349
|
-
});
|
|
49350
|
-
}
|
|
49351
|
-
return redirect(302, '/demo');
|
|
49352
|
-
},
|
|
49353
|
-
};
|
|
49354
|
-
|
|
49355
|
-
function validateUsername(username${ts(": unknown): username is string", ")")} {
|
|
49356
|
-
return (
|
|
49357
|
-
typeof username === 'string' &&
|
|
49358
|
-
username.length >= 3 &&
|
|
49359
|
-
username.length <= 31 &&
|
|
49360
|
-
/^[a-z0-9_-]+$/.test(username)
|
|
49361
|
-
);
|
|
49362
|
-
}
|
|
49363
|
-
|
|
49364
|
-
function validatePassword(password${ts(": unknown): password is string", ")")} {
|
|
49365
|
-
return (
|
|
49366
|
-
typeof password === 'string' &&
|
|
49367
|
-
password.length >= 6 &&
|
|
49368
|
-
password.length <= 255
|
|
49369
|
-
);
|
|
49370
|
-
}
|
|
49371
|
-
`;
|
|
49372
|
-
}
|
|
49373
|
-
},
|
|
49374
|
-
{
|
|
49375
|
-
name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/login/+page.svelte`,
|
|
49376
|
-
condition: ({ options: options2 }) => options2.demo,
|
|
49377
|
-
content({ content, typescript }) {
|
|
49378
|
-
if (content) {
|
|
49379
|
-
log.warn(`Existing ${picocolors.yellow("/demo/login/+page.svelte")} file. Could not update.`);
|
|
49380
|
-
return content;
|
|
49381
|
-
}
|
|
49382
|
-
const [ts] = utils.createPrinter(typescript);
|
|
49383
|
-
return dedent(_a || (_a = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n\n export let form", ";\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';`), ts(": ActionData"));
|
|
49384
|
-
}
|
|
49385
|
-
},
|
|
49386
|
-
// logout
|
|
49387
|
-
{
|
|
49388
|
-
name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/+page.server.${typescript ? "ts" : "js"}`,
|
|
49389
|
-
condition: ({ options: options2 }) => options2.demo,
|
|
49390
|
-
content({ content, typescript }) {
|
|
49391
|
-
if (content) {
|
|
49392
|
-
log.warn(
|
|
49393
|
-
`Existing ${picocolors.yellow("/demo/+page.server.[js|ts]")} file. Could not update.`
|
|
49394
|
-
);
|
|
49395
|
-
return content;
|
|
49396
|
-
}
|
|
49397
|
-
const [ts] = utils.createPrinter(typescript);
|
|
49398
|
-
return dedent`
|
|
49399
|
-
import { lucia } from '$lib/server/auth';
|
|
49400
|
-
import { fail, redirect } from '@sveltejs/kit';
|
|
49401
|
-
${ts(`import type { Actions, PageServerLoad } from './$types';`)}
|
|
49402
|
-
|
|
49403
|
-
export const load${ts(": PageServerLoad")} = async (event) => {
|
|
49404
|
-
if (!event.locals.user) {
|
|
49405
|
-
return redirect(302, '/demo/login');
|
|
49406
|
-
}
|
|
49407
|
-
return {
|
|
49408
|
-
user: event.locals.user,
|
|
49409
|
-
};
|
|
49410
|
-
};
|
|
49411
|
-
|
|
49412
|
-
export const actions${ts(": Actions")} = {
|
|
49413
|
-
logout: async (event) => {
|
|
49414
|
-
if (!event.locals.session) {
|
|
49415
|
-
return fail(401);
|
|
49416
|
-
}
|
|
49417
|
-
await lucia.invalidateSession(event.locals.session.id);
|
|
49418
|
-
const sessionCookie = lucia.createBlankSessionCookie();
|
|
49419
|
-
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
49420
|
-
path: '/',
|
|
49421
|
-
...sessionCookie.attributes,
|
|
49422
|
-
});
|
|
49423
|
-
return redirect(302, '/demo/login');
|
|
49424
|
-
},
|
|
49425
|
-
};
|
|
49426
|
-
`;
|
|
49427
|
-
}
|
|
49428
|
-
},
|
|
49429
|
-
{
|
|
49430
|
-
name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/+page.svelte`,
|
|
49431
|
-
condition: ({ options: options2 }) => options2.demo,
|
|
49432
|
-
content({ content, typescript }) {
|
|
49433
|
-
if (content) {
|
|
49434
|
-
log.warn(`Existing ${picocolors.yellow("/demo/+page.svelte")} file. Could not update.`);
|
|
49435
|
-
return content;
|
|
49436
|
-
}
|
|
49437
|
-
const [ts] = utils.createPrinter(typescript);
|
|
49438
|
-
return dedent(_b || (_b = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n\n export let data", ";\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';`), ts(": PageServerData"));
|
|
49439
|
-
}
|
|
49440
|
-
}
|
|
49441
|
-
],
|
|
49442
|
-
nextSteps: ({ highlighter, options: options2 }) => {
|
|
49443
|
-
const steps = [`Run ${highlighter.command("npm run db:push")} to update your database`];
|
|
49444
|
-
if (options2.demo) {
|
|
49445
|
-
steps.push(`Visit ${highlighter.route("/demo")} route to view the demo`);
|
|
49446
|
-
}
|
|
49447
|
-
return steps;
|
|
49448
|
-
}
|
|
49449
|
-
});
|
|
49450
|
-
function createLuciaType(name) {
|
|
49451
|
-
return {
|
|
49452
|
-
type: "TSPropertySignature",
|
|
49453
|
-
key: {
|
|
49454
|
-
type: "Identifier",
|
|
49455
|
-
name
|
|
49456
|
-
},
|
|
49457
|
-
typeAnnotation: {
|
|
49458
|
-
type: "TSTypeAnnotation",
|
|
49459
|
-
typeAnnotation: {
|
|
49460
|
-
type: "TSUnionType",
|
|
49461
|
-
types: [
|
|
49462
|
-
{
|
|
49463
|
-
type: "TSImportType",
|
|
49464
|
-
argument: { type: "StringLiteral", value: "lucia" },
|
|
49465
|
-
qualifier: {
|
|
49466
|
-
type: "Identifier",
|
|
49467
|
-
// capitalize first letter
|
|
49468
|
-
name: `${name[0].toUpperCase()}${name.slice(1)}`
|
|
49469
|
-
}
|
|
49470
|
-
},
|
|
49471
|
-
{
|
|
49472
|
-
type: "TSNullKeyword"
|
|
49473
|
-
}
|
|
49474
|
-
]
|
|
49475
|
-
}
|
|
49476
|
-
}
|
|
49477
|
-
};
|
|
49478
|
-
}
|
|
49479
|
-
function getAuthHandleContent() {
|
|
49480
|
-
return `
|
|
49481
|
-
async ({ event, resolve }) => {
|
|
49482
|
-
const sessionId = event.cookies.get(lucia.sessionCookieName);
|
|
49483
|
-
if (!sessionId) {
|
|
49484
|
-
event.locals.user = null;
|
|
49485
|
-
event.locals.session = null;
|
|
49486
|
-
return resolve(event);
|
|
49487
|
-
}
|
|
49488
|
-
|
|
49489
|
-
const { session, user } = await lucia.validateSession(sessionId);
|
|
49490
|
-
if (!session) {
|
|
49491
|
-
event.cookies.delete(lucia.sessionCookieName, { path: '/' });
|
|
49492
|
-
}
|
|
49493
|
-
|
|
49494
|
-
if (session?.fresh) {
|
|
49495
|
-
const sessionCookie = lucia.createSessionCookie(session.id);
|
|
49496
|
-
|
|
49497
|
-
event.cookies.set(sessionCookie.name, sessionCookie.value, {
|
|
49498
|
-
path: '/',
|
|
49499
|
-
...sessionCookie.attributes,
|
|
49500
|
-
});
|
|
49501
|
-
}
|
|
49502
|
-
|
|
49503
|
-
event.locals.user = user;
|
|
49504
|
-
event.locals.session = session;
|
|
49505
|
-
|
|
49506
|
-
return resolve(event);
|
|
49507
|
-
};`;
|
|
49508
|
-
}
|
|
49509
|
-
function getCallExpression(ast) {
|
|
49510
|
-
let callExpression;
|
|
49511
|
-
walk$1.walk(ast, {}, {
|
|
49512
|
-
CallExpression(node) {
|
|
49513
|
-
callExpression ?? (callExpression = node);
|
|
49514
|
-
}
|
|
49515
|
-
});
|
|
49516
|
-
return callExpression;
|
|
49517
|
-
}
|
|
49518
|
-
|
|
49519
|
-
var mdsvex = defineAdder({
|
|
49520
|
-
id: "mdsvex",
|
|
49521
|
-
name: "mdsvex",
|
|
49522
|
-
description: "svelte in markdown",
|
|
49523
|
-
environments: { svelte: true, kit: true },
|
|
49524
|
-
documentation: "https://mdsvex.pngwn.io/docs",
|
|
49525
|
-
options: {},
|
|
49526
|
-
packages: [{ name: "mdsvex", version: "^0.11.2", dev: true }],
|
|
49527
|
-
files: [
|
|
49528
|
-
{
|
|
49529
|
-
name: () => "svelte.config.js",
|
|
49530
|
-
content: ({ content }) => {
|
|
49531
|
-
const { ast, generateCode } = parseScript(content);
|
|
49532
|
-
imports.addNamed(ast, "mdsvex", { mdsvex: "mdsvex" });
|
|
49533
|
-
const { value: exportDefault } = exports.defaultExport(ast, object.createEmpty());
|
|
49534
|
-
let preprocessorArray = object.property(exportDefault, "preprocess", array.createEmpty());
|
|
49535
|
-
const isArray = preprocessorArray.type === "ArrayExpression";
|
|
49536
|
-
if (!isArray) {
|
|
49537
|
-
const previousElement = preprocessorArray;
|
|
49538
|
-
preprocessorArray = array.createEmpty();
|
|
49539
|
-
array.push(preprocessorArray, previousElement);
|
|
49540
|
-
object.overrideProperty(exportDefault, "preprocess", preprocessorArray);
|
|
49541
|
-
}
|
|
49542
|
-
const mdsvexCall = _function.call("mdsvex", []);
|
|
49543
|
-
array.push(preprocessorArray, mdsvexCall);
|
|
49544
|
-
const extensionsArray = object.property(exportDefault, "extensions", array.createEmpty());
|
|
49545
|
-
array.push(extensionsArray, ".svelte");
|
|
49546
|
-
array.push(extensionsArray, ".svx");
|
|
49547
|
-
return generateCode();
|
|
49548
|
-
}
|
|
49549
|
-
}
|
|
49550
|
-
]
|
|
49551
|
-
});
|
|
49552
|
-
|
|
49553
48823
|
const comma = ','.charCodeAt(0);
|
|
49554
48824
|
const semicolon = ';'.charCodeAt(0);
|
|
49555
48825
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
@@ -50897,6 +50167,635 @@ class MagicString {
|
|
|
50897
50167
|
}
|
|
50898
50168
|
}
|
|
50899
50169
|
|
|
50170
|
+
var __freeze = Object.freeze;
|
|
50171
|
+
var __defProp = Object.defineProperty;
|
|
50172
|
+
var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __freeze(cooked.slice()) }));
|
|
50173
|
+
var _a, _b;
|
|
50174
|
+
const TABLE_TYPE = {
|
|
50175
|
+
mysql: "mysqlTable",
|
|
50176
|
+
postgresql: "pgTable",
|
|
50177
|
+
sqlite: "sqliteTable"
|
|
50178
|
+
};
|
|
50179
|
+
let drizzleDialect;
|
|
50180
|
+
let schemaPath;
|
|
50181
|
+
const options$2 = defineAdderOptions({
|
|
50182
|
+
demo: {
|
|
50183
|
+
type: "boolean",
|
|
50184
|
+
default: true,
|
|
50185
|
+
question: `Do you want to include a demo? ${picocolors.dim("(includes a login/register page)")}`
|
|
50186
|
+
}
|
|
50187
|
+
});
|
|
50188
|
+
var lucia = defineAdder({
|
|
50189
|
+
id: "lucia",
|
|
50190
|
+
environments: { svelte: false, kit: true },
|
|
50191
|
+
homepage: "https://lucia-next.pages.dev",
|
|
50192
|
+
options: options$2,
|
|
50193
|
+
packages: [
|
|
50194
|
+
{ name: "@oslojs/crypto", version: "^1.0.1", dev: false },
|
|
50195
|
+
{ name: "@oslojs/encoding", version: "^1.1.0", dev: false },
|
|
50196
|
+
// password hashing for demo
|
|
50197
|
+
{
|
|
50198
|
+
name: "@node-rs/argon2",
|
|
50199
|
+
version: "^1.1.0",
|
|
50200
|
+
condition: ({ options: options2 }) => options2.demo,
|
|
50201
|
+
dev: false
|
|
50202
|
+
}
|
|
50203
|
+
],
|
|
50204
|
+
dependsOn: ["drizzle"],
|
|
50205
|
+
files: [
|
|
50206
|
+
{
|
|
50207
|
+
name: ({ typescript }) => `drizzle.config.${typescript ? "ts" : "js"}`,
|
|
50208
|
+
content: ({ content }) => {
|
|
50209
|
+
const { ast, generateCode } = parseScript(content);
|
|
50210
|
+
const isProp = (name, node) => node.key.type === "Identifier" && node.key.name === name;
|
|
50211
|
+
walk$1.walk(ast, {}, {
|
|
50212
|
+
ObjectProperty(node) {
|
|
50213
|
+
if (isProp("dialect", node) && node.value.type === "StringLiteral") {
|
|
50214
|
+
drizzleDialect = node.value.value;
|
|
50215
|
+
}
|
|
50216
|
+
if (isProp("schema", node) && node.value.type === "StringLiteral") {
|
|
50217
|
+
schemaPath = node.value.value;
|
|
50218
|
+
}
|
|
50219
|
+
}
|
|
50220
|
+
});
|
|
50221
|
+
if (!drizzleDialect) {
|
|
50222
|
+
throw new Error("Failed to detect DB dialect in your `drizzle.config.[js|ts]` file");
|
|
50223
|
+
}
|
|
50224
|
+
if (!schemaPath) {
|
|
50225
|
+
throw new Error("Failed to find schema path in your `drizzle.config.[js|ts]` file");
|
|
50226
|
+
}
|
|
50227
|
+
return generateCode();
|
|
50228
|
+
}
|
|
50229
|
+
},
|
|
50230
|
+
{
|
|
50231
|
+
name: () => schemaPath,
|
|
50232
|
+
content: ({ content, options: options2, typescript }) => {
|
|
50233
|
+
const { ast, generateCode } = parseScript(content);
|
|
50234
|
+
const createTable = (name) => _function.call(TABLE_TYPE[drizzleDialect], [name]);
|
|
50235
|
+
const userDecl = variables.declaration(ast, "const", "user", createTable("user"));
|
|
50236
|
+
const sessionDecl = variables.declaration(ast, "const", "session", createTable("session"));
|
|
50237
|
+
const user = exports.namedExport(ast, "user", userDecl);
|
|
50238
|
+
const session = exports.namedExport(ast, "session", sessionDecl);
|
|
50239
|
+
const userTable = getCallExpression(user);
|
|
50240
|
+
const sessionTable = getCallExpression(session);
|
|
50241
|
+
if (!userTable || !sessionTable) {
|
|
50242
|
+
throw new Error("failed to find call expression of `user` or `session`");
|
|
50243
|
+
}
|
|
50244
|
+
if (userTable.arguments.length === 1) {
|
|
50245
|
+
userTable.arguments.push(object.createEmpty());
|
|
50246
|
+
}
|
|
50247
|
+
if (sessionTable.arguments.length === 1) {
|
|
50248
|
+
sessionTable.arguments.push(object.createEmpty());
|
|
50249
|
+
}
|
|
50250
|
+
const userAttributes = userTable.arguments[1];
|
|
50251
|
+
const sessionAttributes = sessionTable.arguments[1];
|
|
50252
|
+
if (userAttributes?.type !== "ObjectExpression" || sessionAttributes?.type !== "ObjectExpression") {
|
|
50253
|
+
throw new Error("unexpected shape of `user` or `session` table definition");
|
|
50254
|
+
}
|
|
50255
|
+
if (drizzleDialect === "sqlite") {
|
|
50256
|
+
imports.addNamed(ast, "drizzle-orm/sqlite-core", {
|
|
50257
|
+
sqliteTable: "sqliteTable",
|
|
50258
|
+
text: "text",
|
|
50259
|
+
integer: "integer"
|
|
50260
|
+
});
|
|
50261
|
+
object.overrideProperties(userAttributes, {
|
|
50262
|
+
id: common.expressionFromString(`text('id').primaryKey()`)
|
|
50263
|
+
});
|
|
50264
|
+
if (options2.demo) {
|
|
50265
|
+
object.overrideProperties(userAttributes, {
|
|
50266
|
+
username: common.expressionFromString(`text('username').notNull().unique()`),
|
|
50267
|
+
passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
|
|
50268
|
+
});
|
|
50269
|
+
}
|
|
50270
|
+
object.overrideProperties(sessionAttributes, {
|
|
50271
|
+
id: common.expressionFromString(`text('id').primaryKey()`),
|
|
50272
|
+
userId: common.expressionFromString(
|
|
50273
|
+
`text('user_id').notNull().references(() => user.id)`
|
|
50274
|
+
),
|
|
50275
|
+
expiresAt: common.expressionFromString(
|
|
50276
|
+
`integer('expires_at', { mode: 'timestamp' }).notNull()`
|
|
50277
|
+
)
|
|
50278
|
+
});
|
|
50279
|
+
}
|
|
50280
|
+
if (drizzleDialect === "mysql") {
|
|
50281
|
+
imports.addNamed(ast, "drizzle-orm/mysql-core", {
|
|
50282
|
+
mysqlTable: "mysqlTable",
|
|
50283
|
+
varchar: "varchar",
|
|
50284
|
+
datetime: "datetime"
|
|
50285
|
+
});
|
|
50286
|
+
object.overrideProperties(userAttributes, {
|
|
50287
|
+
id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`)
|
|
50288
|
+
});
|
|
50289
|
+
if (options2.demo) {
|
|
50290
|
+
object.overrideProperties(userAttributes, {
|
|
50291
|
+
username: common.expressionFromString(
|
|
50292
|
+
`varchar('username', { length: 32 }).notNull().unique()`
|
|
50293
|
+
),
|
|
50294
|
+
passwordHash: common.expressionFromString(
|
|
50295
|
+
`varchar('password_hash', { length: 255 }).notNull()`
|
|
50296
|
+
)
|
|
50297
|
+
});
|
|
50298
|
+
}
|
|
50299
|
+
object.overrideProperties(sessionAttributes, {
|
|
50300
|
+
id: common.expressionFromString(`varchar('id', { length: 255 }).primaryKey()`),
|
|
50301
|
+
userId: common.expressionFromString(
|
|
50302
|
+
`varchar('user_id', { length: 255 }).notNull().references(() => user.id)`
|
|
50303
|
+
),
|
|
50304
|
+
expiresAt: common.expressionFromString(`datetime('expires_at').notNull()`)
|
|
50305
|
+
});
|
|
50306
|
+
}
|
|
50307
|
+
if (drizzleDialect === "postgresql") {
|
|
50308
|
+
imports.addNamed(ast, "drizzle-orm/pg-core", {
|
|
50309
|
+
pgTable: "pgTable",
|
|
50310
|
+
text: "text",
|
|
50311
|
+
timestamp: "timestamp"
|
|
50312
|
+
});
|
|
50313
|
+
object.overrideProperties(userAttributes, {
|
|
50314
|
+
id: common.expressionFromString(`text('id').primaryKey()`)
|
|
50315
|
+
});
|
|
50316
|
+
if (options2.demo) {
|
|
50317
|
+
object.overrideProperties(userAttributes, {
|
|
50318
|
+
username: common.expressionFromString(`text('username').notNull().unique()`),
|
|
50319
|
+
passwordHash: common.expressionFromString(`text('password_hash').notNull()`)
|
|
50320
|
+
});
|
|
50321
|
+
}
|
|
50322
|
+
object.overrideProperties(sessionAttributes, {
|
|
50323
|
+
id: common.expressionFromString(`text('id').primaryKey()`),
|
|
50324
|
+
userId: common.expressionFromString(
|
|
50325
|
+
`text('user_id').notNull().references(() => user.id)`
|
|
50326
|
+
),
|
|
50327
|
+
expiresAt: common.expressionFromString(
|
|
50328
|
+
`timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()`
|
|
50329
|
+
)
|
|
50330
|
+
});
|
|
50331
|
+
}
|
|
50332
|
+
let code = generateCode();
|
|
50333
|
+
if (typescript) {
|
|
50334
|
+
if (!code.includes("export type Session =")) {
|
|
50335
|
+
code += "\n\nexport type Session = typeof session.$inferSelect;";
|
|
50336
|
+
}
|
|
50337
|
+
if (!code.includes("export type User =")) {
|
|
50338
|
+
code += "\n\nexport type User = typeof user.$inferSelect;";
|
|
50339
|
+
}
|
|
50340
|
+
}
|
|
50341
|
+
return code;
|
|
50342
|
+
}
|
|
50343
|
+
},
|
|
50344
|
+
{
|
|
50345
|
+
name: ({ kit: kit2, typescript }) => `${kit2?.libDirectory}/server/auth.${typescript ? "ts" : "js"}`,
|
|
50346
|
+
content: ({ content, typescript }) => {
|
|
50347
|
+
const { ast, generateCode } = parseScript(content);
|
|
50348
|
+
imports.addNamespace(ast, "$lib/server/db/schema", "table");
|
|
50349
|
+
imports.addNamed(ast, "$lib/server/db", { db: "db" });
|
|
50350
|
+
imports.addNamed(ast, "@oslojs/encoding", {
|
|
50351
|
+
encodeBase32LowerCaseNoPadding: "encodeBase32LowerCaseNoPadding",
|
|
50352
|
+
encodeHexLowerCase: "encodeHexLowerCase"
|
|
50353
|
+
});
|
|
50354
|
+
imports.addNamed(ast, "@oslojs/crypto/sha2", { sha256: "sha256" });
|
|
50355
|
+
imports.addNamed(ast, "drizzle-orm", { eq: "eq" });
|
|
50356
|
+
const ms = new MagicString(generateCode().trim());
|
|
50357
|
+
const [ts] = utils.createPrinter(typescript);
|
|
50358
|
+
if (!ms.original.includes("const DAY_IN_MS")) {
|
|
50359
|
+
ms.append("\n\nconst DAY_IN_MS = 1000 * 60 * 60 * 24;");
|
|
50360
|
+
}
|
|
50361
|
+
if (!ms.original.includes("export const sessionCookieName")) {
|
|
50362
|
+
ms.append("\n\nexport const sessionCookieName = 'auth-session';");
|
|
50363
|
+
}
|
|
50364
|
+
if (!ms.original.includes("function generateSessionToken")) {
|
|
50365
|
+
const generateSessionToken = dedent`
|
|
50366
|
+
${ts("", "/** @returns {string} */")}
|
|
50367
|
+
function generateSessionToken()${ts(": string")} {
|
|
50368
|
+
const bytes = crypto.getRandomValues(new Uint8Array(20));
|
|
50369
|
+
const token = encodeBase32LowerCaseNoPadding(bytes);
|
|
50370
|
+
return token;
|
|
50371
|
+
}`;
|
|
50372
|
+
ms.append(`
|
|
50373
|
+
|
|
50374
|
+
${generateSessionToken}`);
|
|
50375
|
+
}
|
|
50376
|
+
if (!ms.original.includes("async function createSession")) {
|
|
50377
|
+
const createSession = dedent`
|
|
50378
|
+
${ts("", "/** @param {string} userId */")}
|
|
50379
|
+
export async function createSession(userId${ts(": string")})${ts(": Promise<table.Session>")} {
|
|
50380
|
+
const token = generateSessionToken();
|
|
50381
|
+
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
|
50382
|
+
const session${ts(": table.Session")} = {
|
|
50383
|
+
id: sessionId,
|
|
50384
|
+
userId,
|
|
50385
|
+
expiresAt: new Date(Date.now() + DAY_IN_MS * 30)
|
|
50386
|
+
};
|
|
50387
|
+
await db.insert(table.session).values(session);
|
|
50388
|
+
return session;
|
|
50389
|
+
}`;
|
|
50390
|
+
ms.append(`
|
|
50391
|
+
|
|
50392
|
+
${createSession}`);
|
|
50393
|
+
}
|
|
50394
|
+
if (!ms.original.includes("async function invalidateSession")) {
|
|
50395
|
+
const invalidateSession = dedent`
|
|
50396
|
+
${ts("", "/**")}
|
|
50397
|
+
${ts("", " * @param {string} sessionId")}
|
|
50398
|
+
${ts("", " * @returns {Promise<void>}")}
|
|
50399
|
+
${ts("", " */")}
|
|
50400
|
+
export async function invalidateSession(sessionId${ts(": string")})${ts(": Promise<void>")} {
|
|
50401
|
+
await db.delete(table.session).where(eq(table.session.id, sessionId));
|
|
50402
|
+
}`;
|
|
50403
|
+
ms.append(`
|
|
50404
|
+
|
|
50405
|
+
${invalidateSession}`);
|
|
50406
|
+
}
|
|
50407
|
+
if (!ms.original.includes("async function validateSession")) {
|
|
50408
|
+
const validateSession = dedent`
|
|
50409
|
+
${ts("", "/** @param {string} sessionId */")}
|
|
50410
|
+
export async function validateSession(sessionId${ts(": string")}) {
|
|
50411
|
+
const [result] = await db
|
|
50412
|
+
.select({
|
|
50413
|
+
// Adjust user table here to tweak returned data
|
|
50414
|
+
user: { id: table.user.id, username: table.user.username },
|
|
50415
|
+
session: table.session
|
|
50416
|
+
})
|
|
50417
|
+
.from(table.session)
|
|
50418
|
+
.innerJoin(table.user, eq(table.session.userId, table.user.id))
|
|
50419
|
+
.where(eq(table.session.id, sessionId));
|
|
50420
|
+
|
|
50421
|
+
if (!result) {
|
|
50422
|
+
return { session: null, user: null };
|
|
50423
|
+
}
|
|
50424
|
+
const { session, user } = result;
|
|
50425
|
+
|
|
50426
|
+
const sessionExpired = Date.now() >= session.expiresAt.getTime();
|
|
50427
|
+
if (sessionExpired) {
|
|
50428
|
+
await db.delete(table.session).where(eq(table.session.id, session.id));
|
|
50429
|
+
return { session: null, user: null };
|
|
50430
|
+
}
|
|
50431
|
+
|
|
50432
|
+
const renewSession = Date.now() >= session.expiresAt.getTime() - DAY_IN_MS * 15;
|
|
50433
|
+
if (renewSession) {
|
|
50434
|
+
session.expiresAt = new Date(Date.now() + DAY_IN_MS * 30);
|
|
50435
|
+
await db
|
|
50436
|
+
.update(table.session)
|
|
50437
|
+
.set({ expiresAt: session.expiresAt })
|
|
50438
|
+
.where(eq(table.session.id, session.id));
|
|
50439
|
+
}
|
|
50440
|
+
|
|
50441
|
+
return { session, user };
|
|
50442
|
+
}`;
|
|
50443
|
+
ms.append(`
|
|
50444
|
+
|
|
50445
|
+
${validateSession}`);
|
|
50446
|
+
}
|
|
50447
|
+
if (typescript && !ms.original.includes("export type SessionValidationResult")) {
|
|
50448
|
+
const sessionType = "export type SessionValidationResult = Awaited<ReturnType<typeof validateSession>>;";
|
|
50449
|
+
ms.append(`
|
|
50450
|
+
|
|
50451
|
+
${sessionType}`);
|
|
50452
|
+
}
|
|
50453
|
+
return ms.toString();
|
|
50454
|
+
}
|
|
50455
|
+
},
|
|
50456
|
+
{
|
|
50457
|
+
name: () => "src/app.d.ts",
|
|
50458
|
+
condition: ({ typescript }) => typescript,
|
|
50459
|
+
content: ({ content }) => {
|
|
50460
|
+
const { ast, generateCode } = parseScript(content);
|
|
50461
|
+
const locals = kit.addGlobalAppInterface(ast, "Locals");
|
|
50462
|
+
if (!locals) {
|
|
50463
|
+
throw new Error("Failed detecting `locals` interface in `src/app.d.ts`");
|
|
50464
|
+
}
|
|
50465
|
+
const user = locals.body.body.find((prop) => common.hasTypeProp("user", prop));
|
|
50466
|
+
const session = locals.body.body.find((prop) => common.hasTypeProp("session", prop));
|
|
50467
|
+
if (!user) {
|
|
50468
|
+
locals.body.body.push(createLuciaType("user"));
|
|
50469
|
+
}
|
|
50470
|
+
if (!session) {
|
|
50471
|
+
locals.body.body.push(createLuciaType("session"));
|
|
50472
|
+
}
|
|
50473
|
+
return generateCode();
|
|
50474
|
+
}
|
|
50475
|
+
},
|
|
50476
|
+
{
|
|
50477
|
+
name: ({ typescript }) => `src/hooks.server.${typescript ? "ts" : "js"}`,
|
|
50478
|
+
content: ({ content, typescript }) => {
|
|
50479
|
+
const { ast, generateCode } = parseScript(content);
|
|
50480
|
+
imports.addNamespace(ast, "$lib/server/auth.js", "auth");
|
|
50481
|
+
imports.addNamed(ast, "$app/environment", { dev: "dev" });
|
|
50482
|
+
kit.addHooksHandle(ast, typescript, "auth", getAuthHandleContent());
|
|
50483
|
+
return generateCode();
|
|
50484
|
+
}
|
|
50485
|
+
},
|
|
50486
|
+
// DEMO
|
|
50487
|
+
// login/register
|
|
50488
|
+
{
|
|
50489
|
+
name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/login/+page.server.${typescript ? "ts" : "js"}`,
|
|
50490
|
+
condition: ({ options: options2 }) => options2.demo,
|
|
50491
|
+
content({ content, typescript, kit: kit2 }) {
|
|
50492
|
+
if (content) {
|
|
50493
|
+
const filePath = `${kit2.routesDirectory}/demo/login/+page.server.${typescript ? "ts" : "js"}`;
|
|
50494
|
+
log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
|
|
50495
|
+
return content;
|
|
50496
|
+
}
|
|
50497
|
+
const [ts] = utils.createPrinter(typescript);
|
|
50498
|
+
return dedent`
|
|
50499
|
+
import { hash, verify } from '@node-rs/argon2';
|
|
50500
|
+
import { generateRandomString } from '@oslojs/crypto/random';
|
|
50501
|
+
import { fail, redirect } from '@sveltejs/kit';
|
|
50502
|
+
import { eq } from 'drizzle-orm';
|
|
50503
|
+
import { dev } from '$app/environment';
|
|
50504
|
+
import * as auth from '$lib/server/auth';
|
|
50505
|
+
import { db } from '$lib/server/db';
|
|
50506
|
+
import * as table from '$lib/server/db/schema';
|
|
50507
|
+
${ts(`import type { Actions, PageServerLoad } from './$types';
|
|
50508
|
+
`)}
|
|
50509
|
+
export const load${ts(": PageServerLoad")} = async (event) => {
|
|
50510
|
+
if (event.locals.user) {
|
|
50511
|
+
return redirect(302, '/demo');
|
|
50512
|
+
}
|
|
50513
|
+
return {};
|
|
50514
|
+
};
|
|
50515
|
+
|
|
50516
|
+
export const actions${ts(": Actions")} = {
|
|
50517
|
+
login: async (event) => {
|
|
50518
|
+
const formData = await event.request.formData();
|
|
50519
|
+
const username = formData.get('username');
|
|
50520
|
+
const password = formData.get('password');
|
|
50521
|
+
|
|
50522
|
+
if (!validateUsername(username)) {
|
|
50523
|
+
return fail(400, { message: 'Invalid username' });
|
|
50524
|
+
}
|
|
50525
|
+
if (!validatePassword(password)) {
|
|
50526
|
+
return fail(400, { message: 'Invalid password' });
|
|
50527
|
+
}
|
|
50528
|
+
|
|
50529
|
+
const results = await db
|
|
50530
|
+
.select()
|
|
50531
|
+
.from(table.user)
|
|
50532
|
+
.where(eq(table.user.username, username));
|
|
50533
|
+
|
|
50534
|
+
const existingUser = results.at(0);
|
|
50535
|
+
if (!existingUser) {
|
|
50536
|
+
return fail(400, { message: 'Incorrect username or password' });
|
|
50537
|
+
}
|
|
50538
|
+
|
|
50539
|
+
const validPassword = await verify(existingUser.passwordHash, password, {
|
|
50540
|
+
memoryCost: 19456,
|
|
50541
|
+
timeCost: 2,
|
|
50542
|
+
outputLen: 32,
|
|
50543
|
+
parallelism: 1,
|
|
50544
|
+
});
|
|
50545
|
+
if (!validPassword) {
|
|
50546
|
+
return fail(400, { message: 'Incorrect username or password' });
|
|
50547
|
+
}
|
|
50548
|
+
|
|
50549
|
+
const session = await auth.createSession(existingUser.id);
|
|
50550
|
+
event.cookies.set(auth.sessionCookieName, session.id, {
|
|
50551
|
+
path: '/',
|
|
50552
|
+
sameSite: 'lax',
|
|
50553
|
+
httpOnly: true,
|
|
50554
|
+
expires: session.expiresAt,
|
|
50555
|
+
secure: !dev
|
|
50556
|
+
});
|
|
50557
|
+
|
|
50558
|
+
return redirect(302, '/demo');
|
|
50559
|
+
},
|
|
50560
|
+
register: async (event) => {
|
|
50561
|
+
const formData = await event.request.formData();
|
|
50562
|
+
const username = formData.get('username');
|
|
50563
|
+
const password = formData.get('password');
|
|
50564
|
+
|
|
50565
|
+
if (!validateUsername(username)) {
|
|
50566
|
+
return fail(400, { message: 'Invalid username' });
|
|
50567
|
+
}
|
|
50568
|
+
if (!validatePassword(password)) {
|
|
50569
|
+
return fail(400, { message: 'Invalid password' });
|
|
50570
|
+
}
|
|
50571
|
+
|
|
50572
|
+
const userId = generateUserId();
|
|
50573
|
+
const passwordHash = await hash(password, {
|
|
50574
|
+
// recommended minimum parameters
|
|
50575
|
+
memoryCost: 19456,
|
|
50576
|
+
timeCost: 2,
|
|
50577
|
+
outputLen: 32,
|
|
50578
|
+
parallelism: 1,
|
|
50579
|
+
});
|
|
50580
|
+
|
|
50581
|
+
try {
|
|
50582
|
+
await db.insert(table.user).values({ id: userId, username, passwordHash });
|
|
50583
|
+
|
|
50584
|
+
const session = await auth.createSession(userId);
|
|
50585
|
+
event.cookies.set(auth.sessionCookieName, session.id, {
|
|
50586
|
+
path: '/',
|
|
50587
|
+
sameSite: 'lax',
|
|
50588
|
+
httpOnly: true,
|
|
50589
|
+
expires: session.expiresAt,
|
|
50590
|
+
secure: !dev
|
|
50591
|
+
});
|
|
50592
|
+
} catch (e) {
|
|
50593
|
+
return fail(500, { message: 'An error has occurred' });
|
|
50594
|
+
}
|
|
50595
|
+
return redirect(302, '/demo');
|
|
50596
|
+
},
|
|
50597
|
+
};
|
|
50598
|
+
|
|
50599
|
+
const alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_';
|
|
50600
|
+
|
|
50601
|
+
function generateUserId(length = 21)${ts(": string")} {
|
|
50602
|
+
return generateRandomString({ read: (bytes) => crypto.getRandomValues(bytes) }, alphabet, length);
|
|
50603
|
+
}
|
|
50604
|
+
|
|
50605
|
+
function validateUsername(username${ts(": unknown")})${ts(": username is string")} {
|
|
50606
|
+
return (
|
|
50607
|
+
typeof username === 'string' &&
|
|
50608
|
+
username.length >= 3 &&
|
|
50609
|
+
username.length <= 31 &&
|
|
50610
|
+
/^[a-z0-9_-]+$/.test(username)
|
|
50611
|
+
);
|
|
50612
|
+
}
|
|
50613
|
+
|
|
50614
|
+
function validatePassword(password${ts(": unknown")})${ts(": password is string")} {
|
|
50615
|
+
return (
|
|
50616
|
+
typeof password === 'string' &&
|
|
50617
|
+
password.length >= 6 &&
|
|
50618
|
+
password.length <= 255
|
|
50619
|
+
);
|
|
50620
|
+
}
|
|
50621
|
+
`;
|
|
50622
|
+
}
|
|
50623
|
+
},
|
|
50624
|
+
{
|
|
50625
|
+
name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/login/+page.svelte`,
|
|
50626
|
+
condition: ({ options: options2 }) => options2.demo,
|
|
50627
|
+
content({ content, typescript, kit: kit2 }) {
|
|
50628
|
+
if (content) {
|
|
50629
|
+
const filePath = `${kit2.routesDirectory}/demo/login/+page.svelte`;
|
|
50630
|
+
log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
|
|
50631
|
+
return content;
|
|
50632
|
+
}
|
|
50633
|
+
const [ts] = utils.createPrinter(typescript);
|
|
50634
|
+
return dedent(_a || (_a = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n export let form", ";\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';
|
|
50635
|
+
`), ts(": ActionData"));
|
|
50636
|
+
}
|
|
50637
|
+
},
|
|
50638
|
+
// logout
|
|
50639
|
+
{
|
|
50640
|
+
name: ({ kit: kit2, typescript }) => `${kit2.routesDirectory}/demo/+page.server.${typescript ? "ts" : "js"}`,
|
|
50641
|
+
condition: ({ options: options2 }) => options2.demo,
|
|
50642
|
+
content({ content, typescript, kit: kit2 }) {
|
|
50643
|
+
if (content) {
|
|
50644
|
+
const filePath = `${kit2.routesDirectory}/demo/+page.server.${typescript ? "ts" : "js"}`;
|
|
50645
|
+
log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
|
|
50646
|
+
return content;
|
|
50647
|
+
}
|
|
50648
|
+
const [ts] = utils.createPrinter(typescript);
|
|
50649
|
+
return dedent`
|
|
50650
|
+
import * as auth from '$lib/server/auth';
|
|
50651
|
+
import { fail, redirect } from '@sveltejs/kit';
|
|
50652
|
+
${ts(`import type { Actions, PageServerLoad } from './$types';
|
|
50653
|
+
`)}
|
|
50654
|
+
export const load${ts(": PageServerLoad")} = async (event) => {
|
|
50655
|
+
if (!event.locals.user) {
|
|
50656
|
+
return redirect(302, '/demo/login');
|
|
50657
|
+
}
|
|
50658
|
+
return { user: event.locals.user };
|
|
50659
|
+
};
|
|
50660
|
+
|
|
50661
|
+
export const actions${ts(": Actions")} = {
|
|
50662
|
+
logout: async (event) => {
|
|
50663
|
+
if (!event.locals.session) {
|
|
50664
|
+
return fail(401);
|
|
50665
|
+
}
|
|
50666
|
+
await auth.invalidateSession(event.locals.session.id);
|
|
50667
|
+
event.cookies.delete(auth.sessionCookieName, { path: '/' });
|
|
50668
|
+
|
|
50669
|
+
return redirect(302, '/demo/login');
|
|
50670
|
+
},
|
|
50671
|
+
};
|
|
50672
|
+
`;
|
|
50673
|
+
}
|
|
50674
|
+
},
|
|
50675
|
+
{
|
|
50676
|
+
name: ({ kit: kit2 }) => `${kit2.routesDirectory}/demo/+page.svelte`,
|
|
50677
|
+
condition: ({ options: options2 }) => options2.demo,
|
|
50678
|
+
content({ content, typescript, kit: kit2 }) {
|
|
50679
|
+
if (content) {
|
|
50680
|
+
const filePath = `${kit2.routesDirectory}/demo/+page.svelte`;
|
|
50681
|
+
log.warn(`Existing ${picocolors.yellow(filePath)} file. Could not update.`);
|
|
50682
|
+
return content;
|
|
50683
|
+
}
|
|
50684
|
+
const [ts] = utils.createPrinter(typescript);
|
|
50685
|
+
return dedent(_b || (_b = __template(["\n <script ", ">\n import { enhance } from '$app/forms';\n ", "\n export let data", ";\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';
|
|
50686
|
+
`), ts(": PageServerData"));
|
|
50687
|
+
}
|
|
50688
|
+
}
|
|
50689
|
+
],
|
|
50690
|
+
nextSteps: ({ highlighter, options: options2 }) => {
|
|
50691
|
+
const steps = [`Run ${highlighter.command("npm run db:push")} to update your database schema`];
|
|
50692
|
+
if (options2.demo) {
|
|
50693
|
+
steps.push(`Visit ${highlighter.route("/demo")} route to view the demo`);
|
|
50694
|
+
}
|
|
50695
|
+
return steps;
|
|
50696
|
+
}
|
|
50697
|
+
});
|
|
50698
|
+
function createLuciaType(name) {
|
|
50699
|
+
return {
|
|
50700
|
+
type: "TSPropertySignature",
|
|
50701
|
+
key: {
|
|
50702
|
+
type: "Identifier",
|
|
50703
|
+
name
|
|
50704
|
+
},
|
|
50705
|
+
typeAnnotation: {
|
|
50706
|
+
type: "TSTypeAnnotation",
|
|
50707
|
+
typeAnnotation: {
|
|
50708
|
+
type: "TSIndexedAccessType",
|
|
50709
|
+
objectType: {
|
|
50710
|
+
type: "TSImportType",
|
|
50711
|
+
argument: { type: "StringLiteral", value: "$lib/server/auth" },
|
|
50712
|
+
qualifier: {
|
|
50713
|
+
type: "Identifier",
|
|
50714
|
+
name: "SessionValidationResult"
|
|
50715
|
+
}
|
|
50716
|
+
},
|
|
50717
|
+
indexType: {
|
|
50718
|
+
type: "TSLiteralType",
|
|
50719
|
+
literal: {
|
|
50720
|
+
type: "StringLiteral",
|
|
50721
|
+
value: name
|
|
50722
|
+
}
|
|
50723
|
+
}
|
|
50724
|
+
}
|
|
50725
|
+
}
|
|
50726
|
+
};
|
|
50727
|
+
}
|
|
50728
|
+
function getAuthHandleContent() {
|
|
50729
|
+
return `
|
|
50730
|
+
async ({ event, resolve }) => {
|
|
50731
|
+
const sessionId = event.cookies.get(auth.sessionCookieName);
|
|
50732
|
+
if (!sessionId) {
|
|
50733
|
+
event.locals.user = null;
|
|
50734
|
+
event.locals.session = null;
|
|
50735
|
+
return resolve(event);
|
|
50736
|
+
}
|
|
50737
|
+
|
|
50738
|
+
const { session, user } = await auth.validateSession(sessionId);
|
|
50739
|
+
if (session) {
|
|
50740
|
+
event.cookies.set(auth.sessionCookieName, session.id, {
|
|
50741
|
+
path: '/',
|
|
50742
|
+
sameSite: 'lax',
|
|
50743
|
+
httpOnly: true,
|
|
50744
|
+
expires: session.expiresAt,
|
|
50745
|
+
secure: !dev
|
|
50746
|
+
});
|
|
50747
|
+
} else {
|
|
50748
|
+
event.cookies.delete(auth.sessionCookieName, { path: '/' });
|
|
50749
|
+
}
|
|
50750
|
+
|
|
50751
|
+
event.locals.user = user;
|
|
50752
|
+
event.locals.session = session;
|
|
50753
|
+
|
|
50754
|
+
return resolve(event);
|
|
50755
|
+
};`;
|
|
50756
|
+
}
|
|
50757
|
+
function getCallExpression(ast) {
|
|
50758
|
+
let callExpression;
|
|
50759
|
+
walk$1.walk(ast, {}, {
|
|
50760
|
+
CallExpression(node) {
|
|
50761
|
+
callExpression ?? (callExpression = node);
|
|
50762
|
+
}
|
|
50763
|
+
});
|
|
50764
|
+
return callExpression;
|
|
50765
|
+
}
|
|
50766
|
+
|
|
50767
|
+
var mdsvex = defineAdder({
|
|
50768
|
+
id: "mdsvex",
|
|
50769
|
+
environments: { svelte: true, kit: true },
|
|
50770
|
+
homepage: "https://mdsvex.pngwn.io",
|
|
50771
|
+
options: {},
|
|
50772
|
+
packages: [{ name: "mdsvex", version: "^0.11.2", dev: true }],
|
|
50773
|
+
files: [
|
|
50774
|
+
{
|
|
50775
|
+
name: () => "svelte.config.js",
|
|
50776
|
+
content: ({ content }) => {
|
|
50777
|
+
const { ast, generateCode } = parseScript(content);
|
|
50778
|
+
imports.addNamed(ast, "mdsvex", { mdsvex: "mdsvex" });
|
|
50779
|
+
const { value: exportDefault } = exports.defaultExport(ast, object.createEmpty());
|
|
50780
|
+
let preprocessorArray = object.property(exportDefault, "preprocess", array.createEmpty());
|
|
50781
|
+
const isArray = preprocessorArray.type === "ArrayExpression";
|
|
50782
|
+
if (!isArray) {
|
|
50783
|
+
const previousElement = preprocessorArray;
|
|
50784
|
+
preprocessorArray = array.createEmpty();
|
|
50785
|
+
array.push(preprocessorArray, previousElement);
|
|
50786
|
+
object.overrideProperty(exportDefault, "preprocess", preprocessorArray);
|
|
50787
|
+
}
|
|
50788
|
+
const mdsvexCall = _function.call("mdsvex", []);
|
|
50789
|
+
array.push(preprocessorArray, mdsvexCall);
|
|
50790
|
+
const extensionsArray = object.property(exportDefault, "extensions", array.createEmpty());
|
|
50791
|
+
array.push(extensionsArray, ".svelte");
|
|
50792
|
+
array.push(extensionsArray, ".svx");
|
|
50793
|
+
return generateCode();
|
|
50794
|
+
}
|
|
50795
|
+
}
|
|
50796
|
+
]
|
|
50797
|
+
});
|
|
50798
|
+
|
|
50900
50799
|
function element(tagName, attributes = {}) {
|
|
50901
50800
|
const element2 = new Element(tagName, {}, void 0, index.Tag);
|
|
50902
50801
|
element2.attribs = attributes;
|
|
@@ -50969,10 +50868,8 @@ const options$1 = defineAdderOptions({
|
|
|
50969
50868
|
});
|
|
50970
50869
|
var paraglide = defineAdder({
|
|
50971
50870
|
id: "paraglide",
|
|
50972
|
-
name: "Paraglide",
|
|
50973
|
-
description: "Typesafe i18n with localised routing",
|
|
50974
50871
|
environments: { svelte: false, kit: true },
|
|
50975
|
-
|
|
50872
|
+
homepage: "https://inlang.com",
|
|
50976
50873
|
options: options$1,
|
|
50977
50874
|
packages: [
|
|
50978
50875
|
{
|
|
@@ -51205,10 +51102,8 @@ function parseLanguageTagInput(input) {
|
|
|
51205
51102
|
|
|
51206
51103
|
var playwright = defineAdder({
|
|
51207
51104
|
id: "playwright",
|
|
51208
|
-
name: "Playwright",
|
|
51209
|
-
description: "A testing framework for end-to-end testing",
|
|
51210
51105
|
environments: { svelte: true, kit: true },
|
|
51211
|
-
|
|
51106
|
+
homepage: "https://playwright.dev",
|
|
51212
51107
|
options: {},
|
|
51213
51108
|
packages: [{ name: "@playwright/test", version: "^1.45.3", dev: true }],
|
|
51214
51109
|
files: [
|
|
@@ -51277,10 +51172,8 @@ var playwright = defineAdder({
|
|
|
51277
51172
|
|
|
51278
51173
|
var prettier = defineAdder({
|
|
51279
51174
|
id: "prettier",
|
|
51280
|
-
name: "Prettier",
|
|
51281
|
-
description: "An opinionated code formatter",
|
|
51282
51175
|
environments: { svelte: true, kit: true },
|
|
51283
|
-
|
|
51176
|
+
homepage: "https://prettier.io",
|
|
51284
51177
|
options: {},
|
|
51285
51178
|
packages: [
|
|
51286
51179
|
{ name: "prettier", version: "^3.3.2", dev: true },
|
|
@@ -51370,10 +51263,8 @@ function hasEslint(dependencyVersion) {
|
|
|
51370
51263
|
|
|
51371
51264
|
var routify = defineAdder({
|
|
51372
51265
|
id: "routify",
|
|
51373
|
-
name: "Routify",
|
|
51374
|
-
description: "The Router that Grows With You",
|
|
51375
51266
|
environments: { svelte: true, kit: false },
|
|
51376
|
-
|
|
51267
|
+
homepage: "https://routify.dev",
|
|
51377
51268
|
options: {},
|
|
51378
51269
|
packages: [{ name: "@roxi/routify", version: "next", dev: true }],
|
|
51379
51270
|
files: [
|
|
@@ -51447,10 +51338,8 @@ const routifyDemoHtml = `
|
|
|
51447
51338
|
|
|
51448
51339
|
var storybook = defineAdder({
|
|
51449
51340
|
id: "storybook",
|
|
51450
|
-
name: "Storybook",
|
|
51451
|
-
description: "Build UIs without the grunt work",
|
|
51452
51341
|
environments: { kit: true, svelte: true },
|
|
51453
|
-
|
|
51342
|
+
homepage: "https://storybook.js.org",
|
|
51454
51343
|
options: {},
|
|
51455
51344
|
packages: [],
|
|
51456
51345
|
scripts: [
|
|
@@ -51489,10 +51378,8 @@ const options = defineAdderOptions({
|
|
|
51489
51378
|
var tailwindcss = defineAdder({
|
|
51490
51379
|
id: "tailwindcss",
|
|
51491
51380
|
alias: "tailwind",
|
|
51492
|
-
name: "Tailwind CSS",
|
|
51493
|
-
description: "Rapidly build modern websites without ever leaving your HTML",
|
|
51494
51381
|
environments: { svelte: true, kit: true },
|
|
51495
|
-
|
|
51382
|
+
homepage: "https://tailwindcss.com",
|
|
51496
51383
|
options,
|
|
51497
51384
|
packages: [
|
|
51498
51385
|
{ name: "tailwindcss", version: "^3.4.9", dev: true },
|
|
@@ -51607,10 +51494,8 @@ var tailwindcss = defineAdder({
|
|
|
51607
51494
|
|
|
51608
51495
|
var vitest = defineAdder({
|
|
51609
51496
|
id: "vitest",
|
|
51610
|
-
name: "Vitest",
|
|
51611
|
-
description: "A testing framework powered by Vite",
|
|
51612
51497
|
environments: { svelte: true, kit: true },
|
|
51613
|
-
|
|
51498
|
+
homepage: "https://vitest.dev",
|
|
51614
51499
|
options: {},
|
|
51615
51500
|
packages: [{ name: "vitest", version: "^2.0.4", dev: true }],
|
|
51616
51501
|
files: [
|
|
@@ -51685,45 +51570,31 @@ var vitest = defineAdder({
|
|
|
51685
51570
|
]
|
|
51686
51571
|
});
|
|
51687
51572
|
|
|
51688
|
-
const
|
|
51689
|
-
|
|
51690
|
-
|
|
51691
|
-
|
|
51692
|
-
|
|
51693
|
-
|
|
51694
|
-
|
|
51695
|
-
|
|
51696
|
-
|
|
51697
|
-
|
|
51698
|
-
|
|
51699
|
-
|
|
51700
|
-
|
|
51701
|
-
|
|
51702
|
-
|
|
51703
|
-
}
|
|
51704
|
-
const adderIds = Object.values(adderCategories).flatMap((x) => x);
|
|
51705
|
-
const adderDetails$1 = Object.values(categories$1).flat();
|
|
51706
|
-
function getAdderDetails(name) {
|
|
51707
|
-
const details = adderDetails$1.find((a) => a.id === name);
|
|
51573
|
+
const officialAdders = [
|
|
51574
|
+
prettier,
|
|
51575
|
+
eslint,
|
|
51576
|
+
vitest,
|
|
51577
|
+
playwright,
|
|
51578
|
+
tailwindcss,
|
|
51579
|
+
drizzle,
|
|
51580
|
+
lucia,
|
|
51581
|
+
mdsvex,
|
|
51582
|
+
paraglide,
|
|
51583
|
+
storybook,
|
|
51584
|
+
routify
|
|
51585
|
+
];
|
|
51586
|
+
function getAdderDetails(id) {
|
|
51587
|
+
const details = officialAdders.find((a) => a.id === id);
|
|
51708
51588
|
if (!details) {
|
|
51709
|
-
throw new Error(`Invalid adder
|
|
51589
|
+
throw new Error(`Invalid adder: ${id}`);
|
|
51710
51590
|
}
|
|
51711
51591
|
return details;
|
|
51712
51592
|
}
|
|
51713
51593
|
|
|
51714
|
-
const categories = [
|
|
51715
|
-
"Code Quality",
|
|
51716
|
-
"Testing",
|
|
51717
|
-
"CSS",
|
|
51718
|
-
"Database",
|
|
51719
|
-
"Auth",
|
|
51720
|
-
"Additional Functionality"
|
|
51721
|
-
];
|
|
51722
|
-
|
|
51723
51594
|
function __variableDynamicImportRuntime0__(path) {
|
|
51724
51595
|
switch (path) {
|
|
51725
|
-
case '../../../community-adders/unocss.ts': return import('./unocss-
|
|
51726
|
-
case '../../../community-adders/unplugin-icons.ts': return import('./unplugin-icons-
|
|
51596
|
+
case '../../../community-adders/unocss.ts': return import('./unocss-BUQS5wKg.js');
|
|
51597
|
+
case '../../../community-adders/unplugin-icons.ts': return import('./unplugin-icons-BietOpsP.js');
|
|
51727
51598
|
default: return new Promise(function(resolve, reject) {
|
|
51728
51599
|
(typeof queueMicrotask === 'function' ? queueMicrotask : setTimeout)(
|
|
51729
51600
|
reject.bind(null, new Error("Unknown variable dynamic import: " + path))
|
|
@@ -51853,7 +51724,7 @@ function getGlobalPreconditions(cwd, projectType, adders) {
|
|
|
51853
51724
|
return { success: true, message: void 0 };
|
|
51854
51725
|
}
|
|
51855
51726
|
const messages = addersForInvalidEnvironment.map(
|
|
51856
|
-
(a) => `"${a.
|
|
51727
|
+
(a) => `"${a.id}" does not support "${projectType}"`
|
|
51857
51728
|
);
|
|
51858
51729
|
return { success: false, message: messages.join(" / ") };
|
|
51859
51730
|
}
|
|
@@ -55301,7 +55172,7 @@ const AddersSchema = array$1(string());
|
|
|
55301
55172
|
const AdderOptionFlagsSchema = object$1({
|
|
55302
55173
|
tailwindcss: optional(array$1(string())),
|
|
55303
55174
|
drizzle: optional(array$1(string())),
|
|
55304
|
-
|
|
55175
|
+
lucia: optional(array$1(string())),
|
|
55305
55176
|
paraglide: optional(array$1(string()))
|
|
55306
55177
|
});
|
|
55307
55178
|
const OptionsSchema$1 = strictObject({
|
|
@@ -55311,8 +55182,7 @@ const OptionsSchema$1 = strictObject({
|
|
|
55311
55182
|
community: optional(union([AddersSchema, boolean()])),
|
|
55312
55183
|
...AdderOptionFlagsSchema.entries
|
|
55313
55184
|
});
|
|
55314
|
-
const
|
|
55315
|
-
const aliases = adderDetails.map((c) => c.alias).filter((v2) => v2 !== void 0);
|
|
55185
|
+
const aliases = officialAdders.map((c) => c.alias).filter((v2) => v2 !== void 0);
|
|
55316
55186
|
const addersOptions = getAdderOptionFlags();
|
|
55317
55187
|
const communityDetails = [];
|
|
55318
55188
|
const defaultPkgPath = up();
|
|
@@ -55329,14 +55199,17 @@ const add = new Command("add").description("applies specified adders into a proj
|
|
|
55329
55199
|
);
|
|
55330
55200
|
process$1$1.exit(1);
|
|
55331
55201
|
}
|
|
55332
|
-
const
|
|
55202
|
+
const specifiedAdders = parse$8(AddersSchema, adderArgs);
|
|
55333
55203
|
const options = parse$8(OptionsSchema$1, opts);
|
|
55334
|
-
const
|
|
55204
|
+
const adderIds = officialAdders.map((adder) => adder.id);
|
|
55205
|
+
const invalidAdders = specifiedAdders.filter(
|
|
55206
|
+
(a) => !adderIds.includes(a) && !aliases.includes(a)
|
|
55207
|
+
);
|
|
55335
55208
|
if (invalidAdders.length > 0) {
|
|
55336
55209
|
console.error(`Invalid adders specified: ${invalidAdders.join(", ")}`);
|
|
55337
55210
|
process$1$1.exit(1);
|
|
55338
55211
|
}
|
|
55339
|
-
const selectedAdders = transformAliases(
|
|
55212
|
+
const selectedAdders = transformAliases(specifiedAdders);
|
|
55340
55213
|
runCommand(async () => {
|
|
55341
55214
|
await runAddCommand(options, selectedAdders);
|
|
55342
55215
|
});
|
|
@@ -55344,9 +55217,9 @@ const add = new Command("add").description("applies specified adders into a proj
|
|
|
55344
55217
|
for (const option of addersOptions) {
|
|
55345
55218
|
add.addOption(option);
|
|
55346
55219
|
}
|
|
55347
|
-
async function runAddCommand(options,
|
|
55220
|
+
async function runAddCommand(options, selectedAdderIds) {
|
|
55348
55221
|
var _a;
|
|
55349
|
-
const selectedAdders =
|
|
55222
|
+
const selectedAdders = selectedAdderIds.map((id) => ({
|
|
55350
55223
|
type: "official",
|
|
55351
55224
|
adder: getAdderDetails(id)
|
|
55352
55225
|
}));
|
|
@@ -55404,23 +55277,17 @@ Available options: ${choices.join(", ")}`
|
|
|
55404
55277
|
}
|
|
55405
55278
|
}
|
|
55406
55279
|
if (options.community === true) {
|
|
55407
|
-
const promptOptions = {};
|
|
55408
55280
|
const communityAdders = await Promise.all(
|
|
55409
|
-
communityAdderIds.map(async (id) =>
|
|
55281
|
+
communityAdderIds.map(async (id) => await getCommunityAdder(id))
|
|
55410
55282
|
);
|
|
55411
|
-
const
|
|
55412
|
-
|
|
55413
|
-
|
|
55414
|
-
|
|
55415
|
-
|
|
55416
|
-
|
|
55417
|
-
}));
|
|
55418
|
-
}
|
|
55419
|
-
const selected = await groupMultiselect({
|
|
55283
|
+
const promptOptions = communityAdders.map((adder) => ({
|
|
55284
|
+
value: adder.id,
|
|
55285
|
+
label: adder.id,
|
|
55286
|
+
hint: "https://www.npmjs.com/package/" + adder.id
|
|
55287
|
+
}));
|
|
55288
|
+
const selected = await multiselect({
|
|
55420
55289
|
message: "Which community tools would you like to add to your project?",
|
|
55421
55290
|
options: promptOptions,
|
|
55422
|
-
spacedGroups: true,
|
|
55423
|
-
selectableGroups: false,
|
|
55424
55291
|
required: false
|
|
55425
55292
|
});
|
|
55426
55293
|
if (isCancel(selected)) {
|
|
@@ -55433,7 +55300,7 @@ Available options: ${choices.join(", ")}`
|
|
|
55433
55300
|
options.community = selected;
|
|
55434
55301
|
}
|
|
55435
55302
|
if (Array.isArray(options.community) && options.community.length > 0) {
|
|
55436
|
-
const
|
|
55303
|
+
const adders = options.community.map((id) => {
|
|
55437
55304
|
const hasDirective = Object.values(Directive).some((directive) => id.startsWith(directive));
|
|
55438
55305
|
if (hasDirective) return id;
|
|
55439
55306
|
const validAdder = communityAdderIds.includes(id);
|
|
@@ -55449,15 +55316,8 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55449
55316
|
try {
|
|
55450
55317
|
start("Resolving community adder packages");
|
|
55451
55318
|
const pkgs = await Promise.all(
|
|
55452
|
-
|
|
55453
|
-
|
|
55454
|
-
const packageName = adder?.npm ?? id;
|
|
55455
|
-
const details2 = await getPackageJSON({ cwd: options.cwd, packageName });
|
|
55456
|
-
return {
|
|
55457
|
-
...details2,
|
|
55458
|
-
// prioritize community adder defined repo urls
|
|
55459
|
-
repo: adder?.repo ?? details2.repo
|
|
55460
|
-
};
|
|
55319
|
+
adders.map(async (id) => {
|
|
55320
|
+
return await getPackageJSON({ cwd: options.cwd, packageName: id });
|
|
55461
55321
|
})
|
|
55462
55322
|
);
|
|
55463
55323
|
stop("Resolved community adder packages");
|
|
@@ -55493,30 +55353,20 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55493
55353
|
}
|
|
55494
55354
|
}
|
|
55495
55355
|
if (selectedAdders.length === 0) {
|
|
55496
|
-
const adderOptions = {};
|
|
55497
55356
|
const workspace2 = createWorkspace(options.cwd);
|
|
55498
55357
|
const projectType = workspace2.kit ? "kit" : "svelte";
|
|
55499
|
-
|
|
55500
|
-
|
|
55501
|
-
|
|
55502
|
-
|
|
55503
|
-
|
|
55504
|
-
|
|
55505
|
-
|
|
55506
|
-
|
|
55507
|
-
|
|
55508
|
-
|
|
55509
|
-
};
|
|
55510
|
-
}).filter((c) => !!c);
|
|
55511
|
-
if (categoryOptions.length > 0) {
|
|
55512
|
-
adderOptions[category] = categoryOptions;
|
|
55513
|
-
}
|
|
55514
|
-
}
|
|
55515
|
-
const selected = await groupMultiselect({
|
|
55358
|
+
const adderOptions = officialAdders.map((adder) => {
|
|
55359
|
+
if (projectType === "kit" && !adder.environments.kit) return;
|
|
55360
|
+
if (projectType === "svelte" && !adder.environments.svelte) return;
|
|
55361
|
+
return {
|
|
55362
|
+
label: adder.id,
|
|
55363
|
+
value: adder.id,
|
|
55364
|
+
hint: adder.homepage
|
|
55365
|
+
};
|
|
55366
|
+
}).filter((a) => !!a);
|
|
55367
|
+
const selected = await multiselect({
|
|
55516
55368
|
message: "What would you like to add to your project?",
|
|
55517
55369
|
options: adderOptions,
|
|
55518
|
-
spacedGroups: true,
|
|
55519
|
-
selectableGroups: false,
|
|
55520
55370
|
required: false
|
|
55521
55371
|
});
|
|
55522
55372
|
if (isCancel(selected)) {
|
|
@@ -55526,12 +55376,11 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55526
55376
|
selected.forEach((id) => selectedAdders.push({ type: "official", adder: getAdderDetails(id) }));
|
|
55527
55377
|
}
|
|
55528
55378
|
for (const { adder } of selectedAdders) {
|
|
55529
|
-
const name = adder.name;
|
|
55530
55379
|
const dependents = adder.dependsOn?.filter((dep) => !selectedAdders.some((a) => a.adder.id === dep)) ?? [];
|
|
55531
55380
|
const workspace2 = createWorkspace(options.cwd);
|
|
55532
55381
|
for (const depId of dependents) {
|
|
55533
|
-
const dependent =
|
|
55534
|
-
if (!dependent) throw new Error(`Adder '${
|
|
55382
|
+
const dependent = officialAdders.find((a) => a.id === depId);
|
|
55383
|
+
if (!dependent) throw new Error(`Adder '${adder.id}' depends on an invalid '${depId}'`);
|
|
55535
55384
|
let installed = false;
|
|
55536
55385
|
installed = dependent.packages.every(
|
|
55537
55386
|
// we'll skip the conditions since we don't have any options to supply it
|
|
@@ -55539,7 +55388,7 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55539
55388
|
);
|
|
55540
55389
|
if (installed) continue;
|
|
55541
55390
|
const install = await confirm({
|
|
55542
|
-
message: `The ${pc.bold(pc.cyan(
|
|
55391
|
+
message: `The ${pc.bold(pc.cyan(adder.id))} adder requires ${pc.bold(pc.cyan(depId))} to also be installed. ${pc.green("Install it?")}`
|
|
55543
55392
|
});
|
|
55544
55393
|
if (install !== true) {
|
|
55545
55394
|
cancel("Operation cancelled.");
|
|
@@ -55548,11 +55397,11 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55548
55397
|
selectedAdders.push({ type: "official", adder: dependent });
|
|
55549
55398
|
}
|
|
55550
55399
|
}
|
|
55551
|
-
if (options.preconditions) {
|
|
55400
|
+
if (options.preconditions && selectedAdders.length > 0) {
|
|
55552
55401
|
const { kit } = createWorkspace(options.cwd);
|
|
55553
55402
|
const projectType = kit ? "kit" : "svelte";
|
|
55554
|
-
const
|
|
55555
|
-
const { preconditions } = getGlobalPreconditions(options.cwd, projectType,
|
|
55403
|
+
const adders = selectedAdders.map(({ adder }) => adder);
|
|
55404
|
+
const { preconditions } = getGlobalPreconditions(options.cwd, projectType, adders);
|
|
55556
55405
|
const fails = [];
|
|
55557
55406
|
for (const condition of preconditions) {
|
|
55558
55407
|
const { message, success } = await condition.run();
|
|
@@ -55573,7 +55422,7 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55573
55422
|
}
|
|
55574
55423
|
for (const { adder, type } of selectedAdders) {
|
|
55575
55424
|
const adderId = adder.id;
|
|
55576
|
-
const questionPrefix = selectedAdders.length > 1 ? `${adder.
|
|
55425
|
+
const questionPrefix = selectedAdders.length > 1 ? `${adder.id}: ` : "";
|
|
55577
55426
|
let values = {};
|
|
55578
55427
|
if (type === "official") {
|
|
55579
55428
|
official[adderId] ?? (official[adderId] = {});
|
|
@@ -55626,10 +55475,10 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55626
55475
|
}
|
|
55627
55476
|
let filesToFormat = [];
|
|
55628
55477
|
if (Object.keys({ ...official, ...community }).length > 0) {
|
|
55629
|
-
filesToFormat = await
|
|
55630
|
-
log$1.success("Successfully
|
|
55478
|
+
filesToFormat = await runAdders({ cwd: options.cwd, official, community });
|
|
55479
|
+
log$1.success("Successfully setup integrations");
|
|
55631
55480
|
}
|
|
55632
|
-
let depsStatus;
|
|
55481
|
+
let depsStatus = "skipped";
|
|
55633
55482
|
if (options.install && selectedAdders.length > 0) {
|
|
55634
55483
|
depsStatus = await suggestInstallingDependencies(options.cwd);
|
|
55635
55484
|
}
|
|
@@ -55649,7 +55498,7 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55649
55498
|
const nextStepsMsg = selectedAdders.filter(({ adder }) => adder.nextSteps).map(({ adder }) => {
|
|
55650
55499
|
let adderMessage = "";
|
|
55651
55500
|
if (selectedAdders.length > 1) {
|
|
55652
|
-
adderMessage = `${pc.green(adder.
|
|
55501
|
+
adderMessage = `${pc.green(adder.id)}:
|
|
55653
55502
|
`;
|
|
55654
55503
|
}
|
|
55655
55504
|
const adderNextSteps = adder.nextSteps({
|
|
@@ -55662,16 +55511,16 @@ Available options: ${communityAdderIds.join(", ")}`
|
|
|
55662
55511
|
}).join("\n\n");
|
|
55663
55512
|
if (nextStepsMsg) box(nextStepsMsg, "Next steps");
|
|
55664
55513
|
}
|
|
55665
|
-
async function
|
|
55514
|
+
async function runAdders({
|
|
55666
55515
|
cwd,
|
|
55667
55516
|
official = {},
|
|
55668
55517
|
community = {}
|
|
55669
55518
|
}) {
|
|
55670
|
-
const
|
|
55519
|
+
const adderDetails = Object.keys(official).map((id) => getAdderDetails(id));
|
|
55671
55520
|
const commDetails = Object.keys(community).map(
|
|
55672
55521
|
(id) => communityDetails.find((a) => a.id === id)
|
|
55673
55522
|
);
|
|
55674
|
-
const details =
|
|
55523
|
+
const details = adderDetails.concat(commDetails);
|
|
55675
55524
|
details.sort((a, b) => {
|
|
55676
55525
|
if (!a.dependsOn) return -1;
|
|
55677
55526
|
if (!b.dependsOn) return 1;
|
|
@@ -55689,8 +55538,7 @@ async function installAdders({
|
|
|
55689
55538
|
changedFiles.forEach((file) => filesToFormat.add(file));
|
|
55690
55539
|
await config.postInstall?.(workspace);
|
|
55691
55540
|
if (config.scripts && config.scripts.length > 0) {
|
|
55692
|
-
|
|
55693
|
-
log$1.step(`Running external command ${pc.gray(`(${name})`)}`);
|
|
55541
|
+
log$1.step(`Running external command ${pc.gray(`(${config.id})`)}`);
|
|
55694
55542
|
for (const script of config.scripts) {
|
|
55695
55543
|
if (script.condition?.(workspace) === false) continue;
|
|
55696
55544
|
const { command, args } = resolveCommand(workspace.packageManager, "execute", script.args);
|
|
@@ -55704,7 +55552,7 @@ async function installAdders({
|
|
|
55704
55552
|
);
|
|
55705
55553
|
}
|
|
55706
55554
|
}
|
|
55707
|
-
log$1.success(`Finished running ${
|
|
55555
|
+
log$1.success(`Finished running ${config.id}`);
|
|
55708
55556
|
}
|
|
55709
55557
|
}
|
|
55710
55558
|
return Array.from(filesToFormat);
|
|
@@ -55713,7 +55561,7 @@ function transformAliases(ids) {
|
|
|
55713
55561
|
const set = /* @__PURE__ */ new Set();
|
|
55714
55562
|
for (const id of ids) {
|
|
55715
55563
|
if (aliases.includes(id)) {
|
|
55716
|
-
const adder =
|
|
55564
|
+
const adder = officialAdders.find((a) => a.alias === id);
|
|
55717
55565
|
set.add(adder.id);
|
|
55718
55566
|
} else {
|
|
55719
55567
|
set.add(id);
|
|
@@ -55723,7 +55571,8 @@ function transformAliases(ids) {
|
|
|
55723
55571
|
}
|
|
55724
55572
|
function getAdderOptionFlags() {
|
|
55725
55573
|
const options = [];
|
|
55726
|
-
for (const
|
|
55574
|
+
for (const adder of officialAdders) {
|
|
55575
|
+
const id = adder.id;
|
|
55727
55576
|
const details = getAdderDetails(id);
|
|
55728
55577
|
if (Object.values(details.options).length === 0) continue;
|
|
55729
55578
|
const { defaults, groups } = getOptionChoices(details);
|
|
@@ -55838,7 +55687,7 @@ async function createProject(cwd, options) {
|
|
|
55838
55687
|
});
|
|
55839
55688
|
},
|
|
55840
55689
|
force: async ({ results: { directory: directory2 } }) => {
|
|
55841
|
-
if (fs$3.existsSync(directory2) && fs$3.readdirSync(directory2).length > 0) {
|
|
55690
|
+
if (fs$3.existsSync(directory2) && fs$3.readdirSync(directory2).filter((x) => !x.startsWith(".git")).length > 0) {
|
|
55842
55691
|
const force = await confirm({
|
|
55843
55692
|
message: "Directory not empty. Continue?",
|
|
55844
55693
|
initialValue: false
|
|
@@ -55852,8 +55701,8 @@ async function createProject(cwd, options) {
|
|
|
55852
55701
|
template: () => {
|
|
55853
55702
|
if (options.template) return Promise.resolve(options.template);
|
|
55854
55703
|
return select({
|
|
55855
|
-
message: "Which
|
|
55856
|
-
initialValue: "
|
|
55704
|
+
message: "Which template would you like?",
|
|
55705
|
+
initialValue: "minimal",
|
|
55857
55706
|
options: templates.map((t) => ({ label: t.title, value: t.name, hint: t.description }))
|
|
55858
55707
|
});
|
|
55859
55708
|
},
|
|
@@ -55888,10 +55737,11 @@ async function createProject(cwd, options) {
|
|
|
55888
55737
|
initSpinner.stop("Project created");
|
|
55889
55738
|
if (options.adders) {
|
|
55890
55739
|
await runAddCommand(
|
|
55891
|
-
{ cwd: projectPath, install:
|
|
55740
|
+
{ cwd: projectPath, install: false, preconditions: true, community: [] },
|
|
55892
55741
|
[]
|
|
55893
55742
|
);
|
|
55894
|
-
}
|
|
55743
|
+
}
|
|
55744
|
+
if (options.install) {
|
|
55895
55745
|
await suggestInstallingDependencies(projectPath);
|
|
55896
55746
|
}
|
|
55897
55747
|
return {
|