zone5 0.0.0 → 1.0.1
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/LICENSE +21 -0
- package/README.md +258 -0
- package/dist/cli/index.js +33 -0
- package/dist/cli/index2.js +238 -0
- package/dist/cli/index3.js +53 -0
- package/dist/cli/templates/.zone5.toml +4 -0
- package/dist/cli/templates/app.css +3 -0
- package/dist/cli/templates/layout.svelte +15 -0
- package/dist/cli/templates/layout.ts +1 -0
- package/dist/components/Zone5.svelte +153 -0
- package/dist/components/Zone5.svelte.d.ts +12 -0
- package/dist/components/Zone5Img.svelte +103 -0
- package/dist/components/Zone5Img.svelte.d.ts +10 -0
- package/dist/components/Zone5Lightbox.svelte +131 -0
- package/dist/components/Zone5Lightbox.svelte.d.ts +12 -0
- package/dist/components/Zone5Provider.svelte +68 -0
- package/dist/components/Zone5Provider.svelte.d.ts +9 -0
- package/dist/components/atoms/Button.svelte +40 -0
- package/dist/components/atoms/Button.svelte.d.ts +13 -0
- package/dist/components/atoms/CloseButton.svelte +18 -0
- package/dist/components/atoms/CloseButton.svelte.d.ts +9 -0
- package/dist/components/atoms/NextButton.svelte +19 -0
- package/dist/components/atoms/NextButton.svelte.d.ts +10 -0
- package/dist/components/atoms/PrevButton.svelte +19 -0
- package/dist/components/atoms/PrevButton.svelte.d.ts +10 -0
- package/dist/components/atoms/index.d.ts +4 -0
- package/dist/components/atoms/index.js +5 -0
- package/dist/components/constants.d.ts +17 -0
- package/dist/components/constants.js +17 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.js +7 -0
- package/dist/components/portal.d.ts +4 -0
- package/dist/components/portal.js +26 -0
- package/dist/components/types.d.ts +7 -0
- package/dist/components/types.js +1 -0
- package/dist/config.d.ts +51 -0
- package/dist/config.js +56 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/module.d.ts +19 -0
- package/dist/processor/blurhash.d.ts +7 -0
- package/dist/processor/blurhash.js +37 -0
- package/dist/processor/color.d.ts +5 -0
- package/dist/processor/color.js +32 -0
- package/dist/processor/config.d.ts +12 -0
- package/dist/processor/config.js +9 -0
- package/dist/processor/exif/converters.d.ts +7 -0
- package/dist/processor/exif/converters.js +38 -0
- package/dist/processor/exif/defaults.d.ts +17 -0
- package/dist/processor/exif/defaults.js +17 -0
- package/dist/processor/exif/exif.d.ts +34 -0
- package/dist/processor/exif/exif.js +43 -0
- package/dist/processor/exif/index.d.ts +1 -0
- package/dist/processor/exif/index.js +1 -0
- package/dist/processor/exif/types.d.ts +4 -0
- package/dist/processor/exif/types.js +1 -0
- package/dist/processor/file.d.ts +3 -0
- package/dist/processor/file.js +28 -0
- package/dist/processor/index.d.ts +27 -0
- package/dist/processor/index.js +70 -0
- package/dist/processor/variants.d.ts +13 -0
- package/dist/processor/variants.js +83 -0
- package/dist/remark.d.ts +5 -0
- package/dist/remark.js +268 -0
- package/dist/stores/index.d.ts +1 -0
- package/dist/stores/index.js +1 -0
- package/dist/stores/registry.svelte.d.ts +22 -0
- package/dist/stores/registry.svelte.js +100 -0
- package/dist/test-setup.d.ts +9 -0
- package/dist/test-setup.js +25 -0
- package/dist/vite.d.ts +2 -0
- package/dist/vite.js +158 -0
- package/package.json +144 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Christian Wygoda
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Zone5
|
|
2
|
+
|
|
3
|
+
Image gallery system for SvelteKit with optimized image processing, lightbox functionality, and MDX support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🖼️ Optimized image processing with variants, blurhash, and color extraction
|
|
8
|
+
- 🔍 Lightbox component with keyboard navigation
|
|
9
|
+
- 📝 MDX integration for markdown-based galleries
|
|
10
|
+
- 🎨 Tailwind CSS 4 support
|
|
11
|
+
- ⚡ Vite plugin for automatic image processing
|
|
12
|
+
- 🛠️ CLI tool for quick project scaffolding
|
|
13
|
+
|
|
14
|
+
## CLI Tool
|
|
15
|
+
|
|
16
|
+
The `zone5` CLI tool helps you quickly create a new SvelteKit gallery project:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx zone5 create <input-folder> <output-folder> [options]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Options
|
|
23
|
+
|
|
24
|
+
- `-m, --mode <type>` - How to handle images: copy, link, or move (default: copy)
|
|
25
|
+
- `-p, --package-manager <pm>` - Package manager: npm, pnpm, yarn, bun, or skip (default: npm)
|
|
26
|
+
- `--no-interactive` - Skip prompts and use defaults
|
|
27
|
+
|
|
28
|
+
### Example
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx zone5 create ./my-photos ./my-gallery --package-manager pnpm
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Usage in SvelteKit Projects
|
|
35
|
+
|
|
36
|
+
### Installation
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install zone5
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Basic Setup
|
|
43
|
+
|
|
44
|
+
1. Add the Vite plugin to your `vite.config.ts`:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { sveltekit } from '@sveltejs/kit/vite';
|
|
48
|
+
import { zone5 } from 'zone5/vite';
|
|
49
|
+
import { defineConfig } from 'vite';
|
|
50
|
+
|
|
51
|
+
export default defineConfig({
|
|
52
|
+
plugins: [zone5(), sveltekit()],
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
2. Wrap your layout with `Zone5Provider`:
|
|
57
|
+
|
|
58
|
+
```svelte
|
|
59
|
+
<script>
|
|
60
|
+
import { Zone5Provider } from 'zone5/components';
|
|
61
|
+
</script>
|
|
62
|
+
|
|
63
|
+
<Zone5Provider>
|
|
64
|
+
<slot />
|
|
65
|
+
</Zone5Provider>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. Create a `.zone5.toml` config file:
|
|
69
|
+
|
|
70
|
+
```toml
|
|
71
|
+
[base]
|
|
72
|
+
root = "src/routes"
|
|
73
|
+
cache = ".zone5"
|
|
74
|
+
namespace = "@zone5"
|
|
75
|
+
|
|
76
|
+
[processor]
|
|
77
|
+
widths = [400, 800, 1200, 1600, 2400]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Using in Components
|
|
81
|
+
|
|
82
|
+
```svelte
|
|
83
|
+
<script>
|
|
84
|
+
import { Zone5 } from 'zone5/components';
|
|
85
|
+
|
|
86
|
+
import image1 from './photo1.jpg?z5';
|
|
87
|
+
import image2 from './photo2.jpg?z5';
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<Zone5 images={[image1, image2]} />
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Using in Markdown/MDX
|
|
94
|
+
|
|
95
|
+
Add the remark plugin to your `svelte.config.js`:
|
|
96
|
+
|
|
97
|
+
```javascript
|
|
98
|
+
import { remarkZ5Images } from 'zone5/remark';
|
|
99
|
+
import { mdsvex } from 'mdsvex';
|
|
100
|
+
|
|
101
|
+
export default {
|
|
102
|
+
preprocess: [
|
|
103
|
+
mdsvex({
|
|
104
|
+
extensions: ['.md'],
|
|
105
|
+
remarkPlugins: [remarkZ5Images],
|
|
106
|
+
}),
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then simply reference images with the `?z5` query parameter:
|
|
112
|
+
|
|
113
|
+
```markdown
|
|
114
|
+

|
|
115
|
+

|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
### Prerequisites
|
|
121
|
+
|
|
122
|
+
- Node.js 18+
|
|
123
|
+
- pnpm (recommended package manager)
|
|
124
|
+
|
|
125
|
+
### Getting Started
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Install dependencies
|
|
129
|
+
pnpm install
|
|
130
|
+
|
|
131
|
+
# Run development server
|
|
132
|
+
pnpm dev
|
|
133
|
+
|
|
134
|
+
# Run tests in watch mode
|
|
135
|
+
pnpm test --watch
|
|
136
|
+
|
|
137
|
+
# Type check
|
|
138
|
+
pnpm check
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Project Structure
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
src/
|
|
145
|
+
├── lib/ # Main library code
|
|
146
|
+
│ ├── components/ # Svelte components
|
|
147
|
+
│ ├── processor/ # Image processing pipeline
|
|
148
|
+
│ ├── vite.ts # Vite plugin
|
|
149
|
+
│ ├── remark.ts # Remark MDX plugin
|
|
150
|
+
│ └── config.ts # Configuration loader
|
|
151
|
+
├── cli/ # CLI tool
|
|
152
|
+
└── routes/ # Demo/documentation site
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Testing
|
|
156
|
+
|
|
157
|
+
The project uses a comprehensive test suite organized by purpose:
|
|
158
|
+
|
|
159
|
+
#### `pnpm test` - Unit Tests (⚡ ~2.7s)
|
|
160
|
+
|
|
161
|
+
Fast unit tests for core functionality:
|
|
162
|
+
|
|
163
|
+
- Component tests (portal)
|
|
164
|
+
- Processor tests (blurhash, color, variants, exif)
|
|
165
|
+
- Remark plugin tests
|
|
166
|
+
|
|
167
|
+
**Use this during development** for quick feedback on code changes.
|
|
168
|
+
|
|
169
|
+
To run a single test file:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
pnpm vitest src/lib/processor/blurhash.test.ts
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
#### `pnpm test:ui` - Integration UI Tests
|
|
176
|
+
|
|
177
|
+
Playwright tests on the local project (currently placeholder for future tests).
|
|
178
|
+
|
|
179
|
+
#### `pnpm test:cli` - CLI Integration Tests (~47.8s)
|
|
180
|
+
|
|
181
|
+
Integration tests for CLI functionality:
|
|
182
|
+
|
|
183
|
+
- Project creation and configuration
|
|
184
|
+
- Package manager support (npm, pnpm, yarn, bun)
|
|
185
|
+
- Template file generation
|
|
186
|
+
- Utility functions
|
|
187
|
+
|
|
188
|
+
**Run this before committing** CLI-related changes.
|
|
189
|
+
|
|
190
|
+
#### `pnpm test:e2e` - End-to-End Tests (~24.1s)
|
|
191
|
+
|
|
192
|
+
Playwright E2E tests that validate the complete workflow:
|
|
193
|
+
|
|
194
|
+
- Creates a new project using the CLI
|
|
195
|
+
- Builds the generated project
|
|
196
|
+
- Tests the lightbox UI functionality
|
|
197
|
+
- Validates Tailwind CSS integration
|
|
198
|
+
|
|
199
|
+
**Run this to verify** the complete user experience.
|
|
200
|
+
|
|
201
|
+
#### `pnpm test:all` - All Tests (~74.6s)
|
|
202
|
+
|
|
203
|
+
Runs all test suites in sequence: unit → CLI → E2E.
|
|
204
|
+
|
|
205
|
+
**Run this before releases** to ensure everything works together.
|
|
206
|
+
|
|
207
|
+
### Build Commands
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
pnpm dev # Watch mode for development (full demo site)
|
|
211
|
+
pnpm build # Build the package (runs svelte-package + CLI build + publint)
|
|
212
|
+
pnpm build:cli # Build just the CLI tool
|
|
213
|
+
pnpm build:watch # Build the package in watch mode
|
|
214
|
+
pnpm check # Type checking with svelte-check
|
|
215
|
+
pnpm check:watch # Type checking in watch mode
|
|
216
|
+
pnpm lint # Run ESLint
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Architecture Overview
|
|
220
|
+
|
|
221
|
+
Zone5 consists of four main components:
|
|
222
|
+
|
|
223
|
+
1. **Image Processor** (`src/lib/processor/`) - Uses Sharp to generate image variants, extract EXIF data, create blurhashes, and determine dominant colors. Results are cached in `.zone5/` directory.
|
|
224
|
+
|
|
225
|
+
2. **Vite Plugin** (`src/lib/vite.ts`) - Intercepts `.jpg?z5` imports at build time, processes images, and serves them during development.
|
|
226
|
+
|
|
227
|
+
3. **Remark Plugin** (`src/lib/remark.ts`) - Transforms markdown images with `?z5` query parameters into Zone5 Svelte components.
|
|
228
|
+
|
|
229
|
+
4. **Component System** (`src/lib/components/`) - Svelte 5 components with a centralized registry for managing lightbox state and navigation across multiple galleries.
|
|
230
|
+
|
|
231
|
+
See [CLAUDE.md](./CLAUDE.md) for detailed architecture documentation.
|
|
232
|
+
|
|
233
|
+
### Contributing
|
|
234
|
+
|
|
235
|
+
1. Make your changes
|
|
236
|
+
2. Run `pnpm test` to ensure unit tests pass
|
|
237
|
+
3. Run `pnpm check` to verify types
|
|
238
|
+
4. Run `pnpm lint` to check code style
|
|
239
|
+
5. If you changed the CLI, run `pnpm test:cli`
|
|
240
|
+
6. Before submitting, run `pnpm test:all` to validate everything
|
|
241
|
+
|
|
242
|
+
**Commit Messages:**
|
|
243
|
+
|
|
244
|
+
This project uses [Conventional Commits](https://www.conventionalcommits.org/). Commit messages are validated via Husky hooks.
|
|
245
|
+
|
|
246
|
+
Format: `<type>: <description>`
|
|
247
|
+
|
|
248
|
+
Valid types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
|
|
249
|
+
|
|
250
|
+
Examples:
|
|
251
|
+
|
|
252
|
+
- `feat: add lightbox keyboard navigation`
|
|
253
|
+
- `fix: resolve EXIF parsing error`
|
|
254
|
+
- `docs: update installation instructions`
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command as s } from "commander";
|
|
3
|
+
import { readFileSync as c } from "node:fs";
|
|
4
|
+
import { dirname as l, join as d } from "node:path";
|
|
5
|
+
import { fileURLToPath as g } from "node:url";
|
|
6
|
+
import n from "picocolors";
|
|
7
|
+
import { createProject as f } from "./index2.js";
|
|
8
|
+
const u = l(g(import.meta.url)), k = JSON.parse(c(d(u, "../../package.json"), "utf-8")), t = new s();
|
|
9
|
+
t.name("zone5").description("Image gallery system for SvelteKit").version(k.version);
|
|
10
|
+
t.command("create").description("Create a new SvelteKit project with zone5 image processing").argument("<input-folder>", "Path to folder containing images").argument("<output-folder>", "Path where the new project will be created").option("-m, --mode <type>", "How to handle images: copy, link, or move", "copy").option(
|
|
11
|
+
"-p, --package-manager <pm>",
|
|
12
|
+
"Package manager to use: npm, pnpm, yarn, bun, or skip to not install",
|
|
13
|
+
"npm"
|
|
14
|
+
).option("--no-interactive", "Skip prompts and use defaults").action(async (a, i, p) => {
|
|
15
|
+
const { mode: e, packageManager: o, interactive: m } = p;
|
|
16
|
+
["copy", "link", "move"].includes(e) || (console.error(n.red(`Error: Invalid mode "${e}". Must be one of: copy, link, move`)), process.exit(1)), ["npm", "pnpm", "yarn", "bun", "skip"].includes(o) || (console.error(
|
|
17
|
+
n.red(
|
|
18
|
+
`Error: Invalid package manager "${o}". Must be one of: npm, pnpm, yarn, bun, skip`
|
|
19
|
+
)
|
|
20
|
+
), process.exit(1));
|
|
21
|
+
try {
|
|
22
|
+
await f({
|
|
23
|
+
inputFolder: a,
|
|
24
|
+
outputFolder: i,
|
|
25
|
+
mode: e,
|
|
26
|
+
packageManager: o,
|
|
27
|
+
interactive: m
|
|
28
|
+
});
|
|
29
|
+
} catch (r) {
|
|
30
|
+
console.error(n.red("Error:"), r instanceof Error ? r.message : String(r)), process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
t.parse();
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import f from "fs-extra";
|
|
2
|
+
import { execSync as C } from "node:child_process";
|
|
3
|
+
import { mkdir as h, writeFile as p, copyFile as j, symlink as x, rename as S } from "node:fs/promises";
|
|
4
|
+
import { dirname as $, join as n, resolve as w, basename as u } from "node:path";
|
|
5
|
+
import { fileURLToPath as z } from "node:url";
|
|
6
|
+
import D from "ora";
|
|
7
|
+
import l from "picocolors";
|
|
8
|
+
import I from "prompts";
|
|
9
|
+
import { pathExists as k, isDirectory as b, findImagesRecursive as J } from "./index3.js";
|
|
10
|
+
const T = $(z(import.meta.url)), g = n(T, "templates");
|
|
11
|
+
async function X(e) {
|
|
12
|
+
const { inputFolder: i, outputFolder: o, mode: s, packageManager: a, interactive: d } = e, c = w(i), r = w(o);
|
|
13
|
+
console.log(l.bold(`
|
|
14
|
+
🖼️ zone5
|
|
15
|
+
`));
|
|
16
|
+
const t = D("Validating input folder...").start();
|
|
17
|
+
if (!await k(c))
|
|
18
|
+
throw t.fail(`Input folder does not exist: ${c}`), new Error("Input folder not found");
|
|
19
|
+
if (!await b(c))
|
|
20
|
+
throw t.fail(`Input path is not a directory: ${c}`), new Error("Input path must be a directory");
|
|
21
|
+
t.text = "Scanning for images...";
|
|
22
|
+
const m = await J(c);
|
|
23
|
+
if (m.length === 0)
|
|
24
|
+
throw t.fail("No images found in input folder"), new Error("No images found");
|
|
25
|
+
if (t.succeed(`Found ${l.cyan(m.length.toString())} images`), await k(r))
|
|
26
|
+
throw t.fail(`Output folder already exists: ${r}`), new Error("Output folder must not exist");
|
|
27
|
+
if (d) {
|
|
28
|
+
const { confirmed: y } = await I({
|
|
29
|
+
type: "confirm",
|
|
30
|
+
name: "confirmed",
|
|
31
|
+
message: `Create project at ${l.cyan(r)} with ${l.cyan(m.length.toString())} images (mode: ${l.yellow(s)})?`,
|
|
32
|
+
initial: !0
|
|
33
|
+
});
|
|
34
|
+
y || (console.log(l.dim("Cancelled")), process.exit(0));
|
|
35
|
+
}
|
|
36
|
+
t.start("Creating SvelteKit project..."), await P(r), t.succeed("Created SvelteKit project"), t.start("Adding dependencies to package.json..."), await L(r), t.succeed("Added dependencies to package.json"), a === "skip" ? t.info("Skipped dependency installation") : (t.start("Installing dependencies..."), await N(r, a), t.succeed("Installed dependencies")), t.start(
|
|
37
|
+
`${s === "copy" ? "Copying" : s === "link" ? "Linking" : "Moving"} images...`
|
|
38
|
+
);
|
|
39
|
+
const v = n(r, "src", "routes");
|
|
40
|
+
if (await f.ensureDir(v), await E(m, c, v, s), t.succeed(
|
|
41
|
+
`${s === "copy" ? "Copied" : s === "link" ? "Linked" : "Moved"} ${m.length} images`
|
|
42
|
+
), t.start("Generating gallery page..."), await F(v, m), t.succeed("Generated gallery page"), t.start("Adding template files..."), await A(r), t.succeed("Added template files"), t.start("Configuring Vite..."), await M(r), t.succeed("Configured Vite"), t.start("Configuring Svelte..."), await R(r), t.succeed("Configured Svelte"), t.start("Configuring Tailwind..."), await Z(r), t.succeed("Configured Tailwind"), t.start("Creating zone5 config..."), await _(r), t.succeed("Created zone5 config"), a !== "skip" && (t.start("Running svelte-kit sync..."), await O(r, a), t.succeed("Ran svelte-kit sync")), console.log(l.green(`
|
|
43
|
+
✓ Project created successfully!
|
|
44
|
+
`)), console.log("Next steps:"), console.log(l.cyan(` cd ${u(r)}`)), a === "skip")
|
|
45
|
+
console.log(l.cyan(" npm install # or your preferred package manager")), console.log(l.cyan(" npm run dev"));
|
|
46
|
+
else {
|
|
47
|
+
const y = a === "npm" ? "npm run dev" : `${a} dev`;
|
|
48
|
+
console.log(l.cyan(` ${y}`));
|
|
49
|
+
}
|
|
50
|
+
console.log();
|
|
51
|
+
}
|
|
52
|
+
async function P(e) {
|
|
53
|
+
await h(e, { recursive: !0 });
|
|
54
|
+
const i = {
|
|
55
|
+
name: u(e),
|
|
56
|
+
version: "0.0.1",
|
|
57
|
+
private: !0,
|
|
58
|
+
type: "module",
|
|
59
|
+
scripts: {
|
|
60
|
+
dev: "vite dev",
|
|
61
|
+
build: "vite build",
|
|
62
|
+
preview: "vite preview"
|
|
63
|
+
},
|
|
64
|
+
devDependencies: {},
|
|
65
|
+
dependencies: {}
|
|
66
|
+
};
|
|
67
|
+
await p(n(e, "package.json"), JSON.stringify(i, null, " ")), await f.ensureDir(n(e, "src", "routes")), await f.ensureDir(n(e, "static")), await p(n(e, "src", "app.html"), `<!doctype html>
|
|
68
|
+
<html lang="en">
|
|
69
|
+
<head>
|
|
70
|
+
<meta charset="utf-8" />
|
|
71
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
72
|
+
%sveltekit.head%
|
|
73
|
+
</head>
|
|
74
|
+
<body data-sveltekit-preload-data="hover">
|
|
75
|
+
<div style="display: contents">%sveltekit.body%</div>
|
|
76
|
+
</body>
|
|
77
|
+
</html>
|
|
78
|
+
`);
|
|
79
|
+
}
|
|
80
|
+
async function L(e) {
|
|
81
|
+
const i = n(e, "package.json"), o = JSON.parse(await f.readFile(i, "utf-8"));
|
|
82
|
+
o.devDependencies = {
|
|
83
|
+
"@lucide/svelte": "^0.553.0",
|
|
84
|
+
"@sveltejs/adapter-static": "^3.0.0",
|
|
85
|
+
"@sveltejs/kit": "^2.0.0",
|
|
86
|
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
87
|
+
"@tailwindcss/vite": "^4.0.0",
|
|
88
|
+
zone5: "latest",
|
|
89
|
+
mdsvex: "^0.12.0",
|
|
90
|
+
svelte: "^5.0.0",
|
|
91
|
+
tailwindcss: "^4.0.0",
|
|
92
|
+
typescript: "^5.0.0",
|
|
93
|
+
vite: "^7.0.0"
|
|
94
|
+
};
|
|
95
|
+
const s = process.env.ZONE5_LOCAL_PATH;
|
|
96
|
+
if (s) {
|
|
97
|
+
const a = w(s);
|
|
98
|
+
o.devDependencies.zone5 = `file:${a}`;
|
|
99
|
+
}
|
|
100
|
+
await p(i, JSON.stringify(o, null, " "));
|
|
101
|
+
}
|
|
102
|
+
async function N(e, i) {
|
|
103
|
+
C((() => {
|
|
104
|
+
switch (i) {
|
|
105
|
+
case "npm":
|
|
106
|
+
return "npm install";
|
|
107
|
+
case "pnpm":
|
|
108
|
+
return "pnpm install";
|
|
109
|
+
case "yarn":
|
|
110
|
+
return "yarn install";
|
|
111
|
+
case "bun":
|
|
112
|
+
return "bun install";
|
|
113
|
+
}
|
|
114
|
+
})(), {
|
|
115
|
+
cwd: e,
|
|
116
|
+
stdio: "pipe"
|
|
117
|
+
}), await p(n(e, "svelte.config.js"), `import adapter from '@sveltejs/adapter-static';
|
|
118
|
+
|
|
119
|
+
/** @type {import('@sveltejs/kit').Config} */
|
|
120
|
+
const config = {
|
|
121
|
+
kit: {
|
|
122
|
+
adapter: adapter()
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export default config;
|
|
127
|
+
`), await p(n(e, "vite.config.ts"), `import { sveltekit } from '@sveltejs/vite-plugin-svelte';
|
|
128
|
+
import { defineConfig } from 'vite';
|
|
129
|
+
|
|
130
|
+
export default defineConfig({
|
|
131
|
+
plugins: [sveltekit()]
|
|
132
|
+
});
|
|
133
|
+
`);
|
|
134
|
+
const d = {
|
|
135
|
+
extends: "./.svelte-kit/tsconfig.json",
|
|
136
|
+
compilerOptions: {
|
|
137
|
+
allowJs: !0,
|
|
138
|
+
checkJs: !0,
|
|
139
|
+
esModuleInterop: !0,
|
|
140
|
+
forceConsistentCasingInFileNames: !0,
|
|
141
|
+
resolveJsonModule: !0,
|
|
142
|
+
skipLibCheck: !0,
|
|
143
|
+
sourceMap: !0,
|
|
144
|
+
strict: !0,
|
|
145
|
+
moduleResolution: "bundler"
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
await p(n(e, "tsconfig.json"), JSON.stringify(d, null, " "));
|
|
149
|
+
}
|
|
150
|
+
async function O(e, i) {
|
|
151
|
+
C((() => {
|
|
152
|
+
switch (i) {
|
|
153
|
+
case "npm":
|
|
154
|
+
return "npx svelte-kit sync";
|
|
155
|
+
case "pnpm":
|
|
156
|
+
return "pnpm exec svelte-kit sync";
|
|
157
|
+
case "yarn":
|
|
158
|
+
return "yarn svelte-kit sync";
|
|
159
|
+
case "bun":
|
|
160
|
+
return "bunx svelte-kit sync";
|
|
161
|
+
}
|
|
162
|
+
})(), {
|
|
163
|
+
cwd: e,
|
|
164
|
+
stdio: "pipe"
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
async function E(e, i, o, s) {
|
|
168
|
+
for (const { path: a, relativePath: d } of e) {
|
|
169
|
+
const c = n(o, u(d));
|
|
170
|
+
s === "copy" ? await j(a, c) : s === "link" ? await x(a, c) : s === "move" && await S(a, c);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
async function F(e, i) {
|
|
174
|
+
const s = `# Photo Gallery
|
|
175
|
+
|
|
176
|
+
${i.map(({ relativePath: a }) => {
|
|
177
|
+
const d = u(a);
|
|
178
|
+
return `![${d.replace(/\.[^.]+$/, "")}](./${d}?z5)`;
|
|
179
|
+
}).join(`
|
|
180
|
+
`)}
|
|
181
|
+
`;
|
|
182
|
+
await p(n(e, "+page.md"), s);
|
|
183
|
+
}
|
|
184
|
+
async function A(e) {
|
|
185
|
+
const i = n(g, "layout.svelte"), o = n(e, "src", "routes", "+layout.svelte");
|
|
186
|
+
await f.copy(i, o);
|
|
187
|
+
const s = n(g, "app.css"), a = n(e, "src", "app.css");
|
|
188
|
+
await f.copy(s, a);
|
|
189
|
+
const d = n(g, "layout.ts"), c = n(e, "src", "routes", "+layout.ts");
|
|
190
|
+
await f.copy(d, c);
|
|
191
|
+
}
|
|
192
|
+
async function M(e) {
|
|
193
|
+
const i = n(e, "vite.config.ts");
|
|
194
|
+
await p(i, `import { sveltekit } from '@sveltejs/kit/vite';
|
|
195
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
196
|
+
import { zone5 } from 'zone5/vite';
|
|
197
|
+
import { defineConfig } from 'vite';
|
|
198
|
+
|
|
199
|
+
export default defineConfig({
|
|
200
|
+
plugins: [tailwindcss(), zone5(), sveltekit()]
|
|
201
|
+
});
|
|
202
|
+
`);
|
|
203
|
+
}
|
|
204
|
+
async function R(e) {
|
|
205
|
+
const i = n(e, "svelte.config.js");
|
|
206
|
+
await p(i, `import adapter from '@sveltejs/adapter-static';
|
|
207
|
+
import { mdsvex } from 'mdsvex';
|
|
208
|
+
import { remarkZ5Images } from 'zone5/remark';
|
|
209
|
+
|
|
210
|
+
/** @type {import('@sveltejs/kit').Config} */
|
|
211
|
+
const config = {
|
|
212
|
+
extensions: ['.svelte', '.md'],
|
|
213
|
+
preprocess: [
|
|
214
|
+
mdsvex({
|
|
215
|
+
extensions: ['.md'],
|
|
216
|
+
remarkPlugins: [remarkZ5Images]
|
|
217
|
+
})
|
|
218
|
+
],
|
|
219
|
+
kit: {
|
|
220
|
+
adapter: adapter()
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export default config;
|
|
225
|
+
`);
|
|
226
|
+
}
|
|
227
|
+
async function Z(e) {
|
|
228
|
+
await p(n(e, "tailwind.config.ts"), `/** @type {import('tailwindcss').Config} */
|
|
229
|
+
export default {};
|
|
230
|
+
`);
|
|
231
|
+
}
|
|
232
|
+
async function _(e) {
|
|
233
|
+
const i = n(g, ".zone5.toml"), o = n(e, ".zone5.toml");
|
|
234
|
+
await f.copy(i, o);
|
|
235
|
+
}
|
|
236
|
+
export {
|
|
237
|
+
X as createProject
|
|
238
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { constants as o } from "node:fs";
|
|
2
|
+
import { access as c, stat as f, readdir as u } from "node:fs/promises";
|
|
3
|
+
import { join as p, extname as h } from "node:path";
|
|
4
|
+
const m = /* @__PURE__ */ new Set([
|
|
5
|
+
".jpg",
|
|
6
|
+
".jpeg",
|
|
7
|
+
".png",
|
|
8
|
+
".webp",
|
|
9
|
+
".avif",
|
|
10
|
+
".gif",
|
|
11
|
+
".tiff",
|
|
12
|
+
".tif",
|
|
13
|
+
".heic",
|
|
14
|
+
".heif"
|
|
15
|
+
]);
|
|
16
|
+
async function I(t) {
|
|
17
|
+
try {
|
|
18
|
+
return await c(t, o.F_OK), !0;
|
|
19
|
+
} catch {
|
|
20
|
+
return !1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function x(t) {
|
|
24
|
+
try {
|
|
25
|
+
return (await f(t)).isDirectory();
|
|
26
|
+
} catch {
|
|
27
|
+
return !1;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function l(t) {
|
|
31
|
+
const a = h(t).toLowerCase();
|
|
32
|
+
return m.has(a);
|
|
33
|
+
}
|
|
34
|
+
async function g(t, a = t) {
|
|
35
|
+
const r = await u(t, { withFileTypes: !0 }), i = [];
|
|
36
|
+
for (const e of r) {
|
|
37
|
+
const s = p(t, e.name);
|
|
38
|
+
if (e.isFile() && l(e.name)) {
|
|
39
|
+
const n = s.replace(a + "/", "");
|
|
40
|
+
i.push({ path: s, relativePath: n });
|
|
41
|
+
} else if (e.isDirectory()) {
|
|
42
|
+
const n = await g(s, a);
|
|
43
|
+
i.push(...n);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return i.sort((e, s) => e.relativePath.localeCompare(s.relativePath));
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
g as findImagesRecursive,
|
|
50
|
+
x as isDirectory,
|
|
51
|
+
l as isImage,
|
|
52
|
+
I as pathExists
|
|
53
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Zone5Provider } from 'zone5/components';
|
|
3
|
+
|
|
4
|
+
import '../app.css';
|
|
5
|
+
|
|
6
|
+
const { children } = $props();
|
|
7
|
+
</script>
|
|
8
|
+
|
|
9
|
+
<Zone5Provider>
|
|
10
|
+
<div class="min-h-screen bg-gray-50">
|
|
11
|
+
<main class="container mx-auto px-4 py-8">
|
|
12
|
+
{@render children()}
|
|
13
|
+
</main>
|
|
14
|
+
</div>
|
|
15
|
+
</Zone5Provider>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const prerender = true;
|