@aryagg/create-super-svelte-library 1.0.16
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/README.md +222 -0
- package/cli.js +76 -0
- package/package.json +13 -0
- package/template/.prettierignore +9 -0
- package/template/.prettierrc +15 -0
- package/template/.vscode/extensions.json +3 -0
- package/template/README.md +65 -0
- package/template/_gitignore +24 -0
- package/template/eslint.config.js +41 -0
- package/template/package-lock.json +3714 -0
- package/template/package.json +64 -0
- package/template/src/app.d.ts +13 -0
- package/template/src/app.html +50 -0
- package/template/src/lib/index.ts +0 -0
- package/template/src/lib/sample/index.ts +0 -0
- package/template/src/routes/+layout.svelte +8 -0
- package/template/src/routes/+page.svelte +3 -0
- package/template/tsconfig.json +15 -0
- package/template/vite.config.ts +22 -0
package/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# @aryagg/create-super-svelte-skeleton
|
|
2
|
+
|
|
3
|
+
A CLI scaffolding tool. One command gives you a fully wired Svelte 5 starter — auth, API layer, i18n, offline support, and 20+ components — ready to run.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Create your project
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm create @aryagg/super-svelte-skeleton my-app
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This copies the full template into `my-app/` and runs `npm install` automatically.
|
|
14
|
+
|
|
15
|
+
> `npm create` prepends `create-` to the package name automatically, so `@aryagg/super-svelte-skeleton` resolves to this package (`@aryagg/create-super-svelte-skeleton`).
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. Set up environment variables
|
|
20
|
+
|
|
21
|
+
Three env files are included — each loaded automatically by Vite depending on how you run the app:
|
|
22
|
+
|
|
23
|
+
| File | When it loads |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `.env` | Always (base values, any mode) |
|
|
26
|
+
| `.env.development` | `npm run dev` only |
|
|
27
|
+
| `.env.production` | `npm run build` / `npm run preview` only |
|
|
28
|
+
|
|
29
|
+
Values in the mode-specific file override `.env`.
|
|
30
|
+
|
|
31
|
+
Copy the example file as your starting point:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cp .env.example .env
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**`.env` — shared base**
|
|
38
|
+
```env
|
|
39
|
+
PUBLIC_SITE_NAME="My App"
|
|
40
|
+
PUBLIC_SITE_DESCRIPTION="A high-performance SvelteKit application."
|
|
41
|
+
PUBLIC_API_URL="https://api.myapp.com"
|
|
42
|
+
PUBLIC_CONFIG_ENV="local"
|
|
43
|
+
PUBLIC_BASE_PATH="/app"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**`.env.development` — local dev overrides**
|
|
47
|
+
```env
|
|
48
|
+
PUBLIC_CONFIG_ENV="local"
|
|
49
|
+
PUBLIC_BASE_PATH="/skeleton-local"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**`.env.production` — production build overrides**
|
|
53
|
+
```env
|
|
54
|
+
PUBLIC_CONFIG_ENV="production"
|
|
55
|
+
PUBLIC_BASE_PATH="/prod"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Rules:**
|
|
59
|
+
- No spaces around `=` — `KEY=VALUE`, not `KEY = VALUE`
|
|
60
|
+
- Variables starting with `PUBLIC_` are available in the browser and server
|
|
61
|
+
- Variables without `PUBLIC_` are server-only
|
|
62
|
+
- After editing any `.env` file, stop and restart `npm run dev`
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Configure runtime settings
|
|
67
|
+
|
|
68
|
+
Open `static/config/config.local.json` for local dev (or `config.prod.json` for production).
|
|
69
|
+
The active file is picked based on `PUBLIC_CONFIG_ENV` in your `.env`.
|
|
70
|
+
These files load at runtime — no rebuild needed when you change them.
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"name": "local"
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## 4. Run the app
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd my-app
|
|
84
|
+
npm run dev
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
App starts at `http://localhost:5173`.
|
|
88
|
+
|
|
89
|
+
**Other commands:**
|
|
90
|
+
|
|
91
|
+
| Command | What it does |
|
|
92
|
+
|---|---|
|
|
93
|
+
| `npm run build` | Production build |
|
|
94
|
+
| `npm run preview` | Preview production build locally |
|
|
95
|
+
| `npm run lint` | Run ESLint |
|
|
96
|
+
| `npm run format` | Format with Prettier |
|
|
97
|
+
| `npm run machine-translate` | Auto-fill missing i18n translation keys |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Project structure
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
my-app/
|
|
105
|
+
├── src/
|
|
106
|
+
│ ├── routes/
|
|
107
|
+
│ │ ├── (auth)/ ← login, register, forgot/reset password
|
|
108
|
+
│ │ ├── (protected)/ ← dashboard & admin (auth-gated)
|
|
109
|
+
│ │ ├── settings/ ← settings page
|
|
110
|
+
│ │ └── theme/ ← theme preview page
|
|
111
|
+
│ ├── lib/
|
|
112
|
+
│ │ ├── api/ ← HTTP client, endpoints, services, types
|
|
113
|
+
│ │ ├── components/ ← 20+ reusable UI components
|
|
114
|
+
│ │ ├── stores/ ← auth, config, snackbar, loader state
|
|
115
|
+
│ │ ├── composables/ ← Svelte actions (autoFocus, clickOutside)
|
|
116
|
+
│ │ ├── constants/ ← route names, auth keys
|
|
117
|
+
│ │ ├── utils/ ← helpers (string, date, number, URL, theme)
|
|
118
|
+
│ │ ├── types/ ← shared TypeScript interfaces
|
|
119
|
+
│ │ └── styles/ ← global CSS and Tailwind config
|
|
120
|
+
│ ├── hooks.server.ts ← auth, locale, API key middleware
|
|
121
|
+
│ ├── hooks.client.ts ← client error handling
|
|
122
|
+
│ └── service-worker.ts ← offline cache + request queue
|
|
123
|
+
├── messages/
|
|
124
|
+
│ ├── en.json ← English translations
|
|
125
|
+
│ ├── es.json ← Spanish translations
|
|
126
|
+
│ └── ar.json ← Arabic translations
|
|
127
|
+
├── static/
|
|
128
|
+
│ ├── config/
|
|
129
|
+
│ │ ├── config.local.json ← runtime config for local dev
|
|
130
|
+
│ │ └── config.prod.json ← runtime config for production
|
|
131
|
+
│ ├── theme-light.css
|
|
132
|
+
│ └── theme-dark.css
|
|
133
|
+
├── .env ← your env vars (not committed)
|
|
134
|
+
├── .env.example ← template for env vars
|
|
135
|
+
├── svelte.config.js
|
|
136
|
+
├── vite.config.ts
|
|
137
|
+
└── package.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Features
|
|
143
|
+
|
|
144
|
+
### Authentication
|
|
145
|
+
- Session cookie–based login (httpOnly, secure in production)
|
|
146
|
+
- JWT access + refresh tokens stored in cookie, auto-read by server hooks
|
|
147
|
+
- `/login`, `/register`, `/forgot-password`, `/reset-password` pages — all styled and wired
|
|
148
|
+
- Auth store with role-based helpers (`isAdmin`, `hasRole`, `hasPermission`)
|
|
149
|
+
- 5-level role hierarchy: `GUEST → USER → MANAGER → ADMIN → SUPER_ADMIN`
|
|
150
|
+
- Protected route group `(protected)/` — server layout checks auth before rendering
|
|
151
|
+
|
|
152
|
+
### API layer
|
|
153
|
+
Located in `src/lib/api/`:
|
|
154
|
+
|
|
155
|
+
| Folder | Purpose |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `axiosClient.ts` | Configured axios instance — base URL from env, 30s timeout, auto Bearer token, 401 handler |
|
|
158
|
+
| `http.ts` | Response normalizer + offline-queue-aware request wrapper |
|
|
159
|
+
| `endpoints/` | URL constants with a `buildUrl()` param helper |
|
|
160
|
+
| `services/` | Functions for every API call (login, register, me, logout, refresh, list, get, update, remove) |
|
|
161
|
+
| `types/` | TypeScript interfaces for all payloads and responses |
|
|
162
|
+
|
|
163
|
+
### Offline support
|
|
164
|
+
- Service worker with cache-first for static assets and network-first for API/pages
|
|
165
|
+
- IndexedDB sync queue — requests made offline are stored and replayed when network returns
|
|
166
|
+
- Background Sync API (Chrome/Edge) with postMessage fallback (Safari/Firefox)
|
|
167
|
+
|
|
168
|
+
### i18n (multi-language)
|
|
169
|
+
- **Paraglide** (`@inlang/paraglide-sveltekit`) — compile-time-safe translations
|
|
170
|
+
- Languages: English, Spanish, Arabic (RTL supported)
|
|
171
|
+
- Language switcher in `Header.svelte` — persists to localStorage
|
|
172
|
+
- To add a language: add `messages/xx.json`, register in `project.inlang/settings.json`, run `npm run machine-translate`
|
|
173
|
+
|
|
174
|
+
### Theming
|
|
175
|
+
- Light / dark CSS variable themes in `static/theme-light.css` and `theme-dark.css`
|
|
176
|
+
- Theme loaded before first paint — no flash
|
|
177
|
+
- Toggle in `Header.svelte` — persists preference
|
|
178
|
+
- Theme preview page at `/theme`
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
### Developer experience
|
|
182
|
+
- Auto-imports via `unplugin-auto-import` — no need to import `onMount`, `goto`, `fade`, etc.
|
|
183
|
+
- Path aliases — `$components`, `$stores`, `$utils`, `$lib`
|
|
184
|
+
- TypeScript strict mode — unused locals/params flagged
|
|
185
|
+
- ESLint + Prettier preconfigured
|
|
186
|
+
- VS Code extensions and debugger configured out of the box
|
|
187
|
+
- Version polling — layout detects new deploys and reloads automatically
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## How to publish a new version
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# 1. Make your changes inside template/ or cli.js
|
|
195
|
+
|
|
196
|
+
# 2. Bump the version
|
|
197
|
+
npm version patch # 1.0.1 → 1.0.2
|
|
198
|
+
npm version minor # 1.0.0 → 1.1.0
|
|
199
|
+
npm version major # 1.0.0 → 2.0.0
|
|
200
|
+
|
|
201
|
+
# 3. Publish to npm
|
|
202
|
+
npm publish --access public
|
|
203
|
+
|
|
204
|
+
# 4. Clear the npx cache so users get the new version immediately
|
|
205
|
+
npx clear-npx-cache
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
> On Windows, clear manually if needed:
|
|
209
|
+
> `Remove-Item -Recurse -Force "$env:LOCALAPPDATA\npm-cache\_npx"`
|
|
210
|
+
|
|
211
|
+
### What gets published
|
|
212
|
+
|
|
213
|
+
Only `cli.js` and the `template/` folder are included in the npm tarball (controlled by the `files` field in `package.json`). This README and other repo files are not published.
|
|
214
|
+
|
|
215
|
+
### Repo structure
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
super-duper-skeleton-svelte/
|
|
219
|
+
├── cli.js ← scaffolding script (entry point)
|
|
220
|
+
├── package.json ← package config (name, version, bin, files)
|
|
221
|
+
└── template/ ← everything here gets copied into the new project
|
|
222
|
+
```
|
package/cli.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
import { execSync } from "child_process";
|
|
6
|
+
|
|
7
|
+
// ESM doesn't have __dirname (ESM is browser‑compatible, and browsers don’t have __dirname), so we derive it from the current file's URL
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url)); //( import.meta.url full URL of the current file.)
|
|
9
|
+
|
|
10
|
+
// Second CLI arg is the project name; default to "svelte-library" if omitted
|
|
11
|
+
const target = process.argv[2] || "svelte-library";
|
|
12
|
+
|
|
13
|
+
// Bail early if the target folder already exists to avoid overwriting anything
|
|
14
|
+
if (fs.existsSync(target)) {
|
|
15
|
+
console.error(`Error: directory "${target}" already exists.`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// The template folder ships inside the npm package next to this file
|
|
20
|
+
const templateDir = path.join(__dirname, "template");
|
|
21
|
+
if (!fs.existsSync(templateDir)) {
|
|
22
|
+
console.error(`Error: template directory not found at ${templateDir}`);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
console.log(`Creating project: ${target}`);
|
|
27
|
+
|
|
28
|
+
// These top-level folders inside the template are dev/build artifacts — skip them
|
|
29
|
+
const SKIP_DIRS = new Set(["node_modules", ".svelte-kit", ".git", ".claude"]);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
fs.cpSync(templateDir, target, {
|
|
33
|
+
recursive: true,
|
|
34
|
+
// Filter runs on absolute paths, so we use relative path from templateDir
|
|
35
|
+
// to avoid false matches against "node_modules" in the npm cache path itself
|
|
36
|
+
filter: (src) => {
|
|
37
|
+
const rel = path.relative(templateDir, src);
|
|
38
|
+
|
|
39
|
+
// Keep root itself
|
|
40
|
+
if (!rel) return true;
|
|
41
|
+
|
|
42
|
+
const parts = rel.split(path.sep);
|
|
43
|
+
|
|
44
|
+
// Skip only actual directories named in SKIP_DIRS
|
|
45
|
+
return !parts.some((part) => SKIP_DIRS.has(part));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// npm strips .gitignore from published packages, so the template stores them as _gitignore
|
|
50
|
+
const renameGitignores = (dir) => {
|
|
51
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
52
|
+
const full = path.join(dir, entry.name);
|
|
53
|
+
if (entry.isDirectory()) renameGitignores(full);
|
|
54
|
+
else if (entry.name === "_gitignore") fs.renameSync(full, path.join(dir, "."));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
renameGitignores(target);
|
|
58
|
+
|
|
59
|
+
// Rename the package to match the new project folder and drop the private flag
|
|
60
|
+
const pkgPath = path.join(target, "package.json");
|
|
61
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
62
|
+
pkg.name = path.basename(target);
|
|
63
|
+
delete pkg.private;
|
|
64
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, "\t") + "\n");
|
|
65
|
+
|
|
66
|
+
console.log("Installing dependencies...");
|
|
67
|
+
// Run npm install inside the newly created project folder
|
|
68
|
+
execSync("npm install", { cwd: target, stdio: "inherit" });
|
|
69
|
+
|
|
70
|
+
console.log("\nDone!");
|
|
71
|
+
console.log(` cd ${target}`);
|
|
72
|
+
console.log(" npm run dev");
|
|
73
|
+
} catch (err) {
|
|
74
|
+
console.error("Error during scaffolding:", err.message);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Svelte library
|
|
2
|
+
|
|
3
|
+
Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
|
|
4
|
+
|
|
5
|
+
Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
|
|
6
|
+
|
|
7
|
+
## Creating a project
|
|
8
|
+
|
|
9
|
+
If you're seeing this, you've probably already done this step. Congrats!
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
# create a new project in the current directory
|
|
13
|
+
npx sv create
|
|
14
|
+
|
|
15
|
+
# create a new project in my-app
|
|
16
|
+
npx sv create my-app
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
To recreate this project with the same configuration:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
# recreate this project
|
|
23
|
+
npx sv@0.16.1 create --template library --types ts --add prettier eslint --install npm ui-kit
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Developing
|
|
27
|
+
|
|
28
|
+
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm run dev
|
|
32
|
+
|
|
33
|
+
# or start the server and open the app in a new browser tab
|
|
34
|
+
npm run dev -- --open
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
|
|
38
|
+
|
|
39
|
+
## Building
|
|
40
|
+
|
|
41
|
+
To build your library:
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
npm pack
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
To create a production version of your showcase app:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm run build
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
You can preview the production build with `npm run preview`.
|
|
54
|
+
|
|
55
|
+
> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
|
|
56
|
+
|
|
57
|
+
## Publishing
|
|
58
|
+
|
|
59
|
+
Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
|
|
60
|
+
|
|
61
|
+
To publish your library to [npm](https://www.npmjs.com):
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
npm publish
|
|
65
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
node_modules
|
|
2
|
+
|
|
3
|
+
# Output
|
|
4
|
+
.output
|
|
5
|
+
.vercel
|
|
6
|
+
.netlify
|
|
7
|
+
.wrangler
|
|
8
|
+
/.svelte-kit
|
|
9
|
+
/build
|
|
10
|
+
/dist
|
|
11
|
+
|
|
12
|
+
# OS
|
|
13
|
+
.DS_Store
|
|
14
|
+
Thumbs.db
|
|
15
|
+
|
|
16
|
+
# Env
|
|
17
|
+
.env
|
|
18
|
+
.env.*
|
|
19
|
+
!.env.example
|
|
20
|
+
!.env.test
|
|
21
|
+
|
|
22
|
+
# Vite
|
|
23
|
+
vite.config.js.timestamp-*
|
|
24
|
+
vite.config.ts.timestamp-*
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import prettier from 'eslint-config-prettier';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import js from '@eslint/js';
|
|
4
|
+
import svelte from 'eslint-plugin-svelte';
|
|
5
|
+
import { defineConfig, includeIgnoreFile } from 'eslint/config';
|
|
6
|
+
import globals from 'globals';
|
|
7
|
+
import ts from 'typescript-eslint';
|
|
8
|
+
|
|
9
|
+
const gitignorePath = path.resolve(import.meta.dirname, '.gitignore');
|
|
10
|
+
|
|
11
|
+
export default defineConfig(
|
|
12
|
+
includeIgnoreFile(gitignorePath),
|
|
13
|
+
js.configs.recommended,
|
|
14
|
+
ts.configs.recommended,
|
|
15
|
+
svelte.configs.recommended,
|
|
16
|
+
prettier,
|
|
17
|
+
svelte.configs.prettier,
|
|
18
|
+
{
|
|
19
|
+
languageOptions: { globals: { ...globals.browser, ...globals.node } },
|
|
20
|
+
rules: {
|
|
21
|
+
// typescript-eslint strongly recommend that you do not use the no-undef lint rule on TypeScript projects.
|
|
22
|
+
// see: https://typescript-eslint.io/troubleshooting/faqs/eslint/#i-get-errors-from-the-no-undef-rule-about-global-variables-not-being-defined-even-though-there-are-no-typescript-errors
|
|
23
|
+
'no-undef': 'off'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
|
|
28
|
+
languageOptions: {
|
|
29
|
+
parserOptions: {
|
|
30
|
+
projectService: true,
|
|
31
|
+
extraFileExtensions: ['.svelte'],
|
|
32
|
+
parser: ts.parser
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
// Override or add rule settings here, such as:
|
|
38
|
+
// 'svelte/button-has-type': 'error'
|
|
39
|
+
rules: {}
|
|
40
|
+
}
|
|
41
|
+
);
|