pwa-sv 1.1.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/AGENTS-for-pwa.md +211 -0
- package/AGENTS.md +141 -0
- package/README.md +182 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +58 -0
- package/dist/cli.js.map +1 -0
- package/dist/deps-manager.d.ts.map +1 -0
- package/dist/deps-manager.js +119 -0
- package/dist/deps-manager.js.map +1 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +229 -0
- package/dist/engine.js.map +1 -0
- package/dist/process-fs-handler.d.ts.map +1 -0
- package/dist/process-fs-handler.js +1199 -0
- package/dist/process-fs-handler.js.map +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
- package/pnpm-workspace.yaml +2 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
|
|
2
|
+
# Functional Programming Guidelines for AI Agents
|
|
3
|
+
|
|
4
|
+
This document provides explicit instructions for AI agents to follow functional programming paradigms when generating or modifying code. Adhere strictly to these principles.
|
|
5
|
+
|
|
6
|
+
## Core Functional Programming Principles
|
|
7
|
+
|
|
8
|
+
### Immutability & Pure Functions
|
|
9
|
+
- **Prefer immutability** - Use immutable data patterns wherever possible
|
|
10
|
+
- **Pure functions** - Functions should not produce side effects and should return the same output for same inputs
|
|
11
|
+
- **Immutable data operations** - Use non-mutating methods for objects and arrays
|
|
12
|
+
|
|
13
|
+
### Error Handling with Effect Types
|
|
14
|
+
- **NO exceptions** - Use `Effect<T, E>` types from `effect` library instead of throwing errors
|
|
15
|
+
- **Explicit error handling** - All possible errors must be represented in return types
|
|
16
|
+
- **Predictable control flow** - Use `map`, `flatMap`, `match` for error handling chains
|
|
17
|
+
|
|
18
|
+
### TypeScript-First Development
|
|
19
|
+
- **Proper TypeScript syntax only** - NO JSDoc type annotations allowed
|
|
20
|
+
- **Explicit type annotations** - All functions, parameters, and returns must have TypeScript types
|
|
21
|
+
- **Generic types** - Use TypeScript generics for reusable, type-safe code
|
|
22
|
+
|
|
23
|
+
## Implementation Rules
|
|
24
|
+
|
|
25
|
+
### Function Design
|
|
26
|
+
```typescript
|
|
27
|
+
// ✅ CORRECT - Pure function with Effect type
|
|
28
|
+
import { Effect, pipe } from "effect";
|
|
29
|
+
|
|
30
|
+
const processUser = (user: User): Effect.Effect<ProcessedUser, ValidationError> => {
|
|
31
|
+
return pipe(
|
|
32
|
+
Effect.succeed(user),
|
|
33
|
+
Effect.andThen(validateUser),
|
|
34
|
+
Effect.map(transformUser),
|
|
35
|
+
Effect.map(enrichUserData)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ❌ INCORRECT - Throws exceptions, mutable parameters
|
|
40
|
+
function processUser(user: User): ProcessedUser {
|
|
41
|
+
if (!user.valid) throw new Error("Invalid user");
|
|
42
|
+
user.processed = true; // Mutation!
|
|
43
|
+
return user;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### State Management in Svelte Components
|
|
48
|
+
```typescript
|
|
49
|
+
// ✅ CORRECT - Svelte reactive declarations with proper typing
|
|
50
|
+
<script lang="ts">
|
|
51
|
+
// Svelte component state - let is required for reactivity
|
|
52
|
+
let count = $state<number>(0);
|
|
53
|
+
let users = $state<ReadonlyArray<User>>([]);
|
|
54
|
+
|
|
55
|
+
// Immutable updates to Svelte state
|
|
56
|
+
const addUser = (newUser: User): void => {
|
|
57
|
+
users = [...users, newUser]; // ✅ Correct - immutable update
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const updateUser = (id: string, updates: Partial<User>): void => {
|
|
61
|
+
users = users.map(user =>
|
|
62
|
+
user.id === id ? { ...user, ...updates } : user
|
|
63
|
+
);
|
|
64
|
+
};
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
// ❌ INCORRECT - Direct mutation of Svelte state
|
|
68
|
+
<script lang="ts">
|
|
69
|
+
let users = $state<User[]>([]);
|
|
70
|
+
|
|
71
|
+
const addUser = (newUser: User): void => {
|
|
72
|
+
users.push(newUser); // ❌ Mutation - avoid this pattern
|
|
73
|
+
};
|
|
74
|
+
</script>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Pure TypeScript Modules (Non-Svelte)
|
|
78
|
+
```typescript
|
|
79
|
+
// ✅ CORRECT - Pure functional module with const
|
|
80
|
+
import { Effect } from "effect";
|
|
81
|
+
|
|
82
|
+
export const processUsers = (users: ReadonlyArray<User>): Effect.Effect<ReadonlyArray<ProcessedUser>, Error> => {
|
|
83
|
+
return Effect.gen(function*() {
|
|
84
|
+
const validUsers = yield* Effect.succeed(users.filter(isValidUser));
|
|
85
|
+
return yield* Effect.forEach(validUsers, processUser);
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// ❌ INCORRECT - Mutable variables in pure TypeScript
|
|
90
|
+
export let processedUsers: User[] = []; // ❌ Avoid module-level mutable variables
|
|
91
|
+
|
|
92
|
+
export function addUser(user: User): void {
|
|
93
|
+
processedUsers.push(user); // ❌ Mutation
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Error Handling Patterns
|
|
98
|
+
```typescript
|
|
99
|
+
// ✅ CORRECT - Using effect
|
|
100
|
+
import { Effect, pipe } from "effect";
|
|
101
|
+
|
|
102
|
+
const fetchUser = (id: string): Effect.Effect<User, NetworkError | NotFoundError> => {
|
|
103
|
+
return pipe(
|
|
104
|
+
Effect.try({
|
|
105
|
+
try: () => apiCall(id),
|
|
106
|
+
catch: (error) => error as NetworkError
|
|
107
|
+
}),
|
|
108
|
+
Effect.andThen(validateResponse),
|
|
109
|
+
Effect.map(parseUserData)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Usage with proper handling
|
|
114
|
+
const result = pipe(
|
|
115
|
+
fetchUser('123'),
|
|
116
|
+
Effect.match({
|
|
117
|
+
onFailure: (error) => { /* handle error */ },
|
|
118
|
+
onSuccess: (user) => { /* handle success */ }
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Svelte 5 Specific Guidelines
|
|
124
|
+
|
|
125
|
+
### State Management
|
|
126
|
+
- Use `let` with `$state<T>()` for Svelte component reactive state
|
|
127
|
+
- Use immutable patterns when updating Svelte state (spread operator, map, filter)
|
|
128
|
+
- Prefer `readonly` types for state that shouldn't be mutated externally
|
|
129
|
+
- Use `$effect()` for side effects with proper TypeScript typing
|
|
130
|
+
|
|
131
|
+
### Component Patterns
|
|
132
|
+
```typescript
|
|
133
|
+
// ✅ CORRECT - Functional Svelte component with immutable patterns
|
|
134
|
+
<script lang="ts">
|
|
135
|
+
// Svelte state declarations use let + $state
|
|
136
|
+
let count = $state<number>(0);
|
|
137
|
+
let items = $state<ReadonlyArray<string>>([]);
|
|
138
|
+
|
|
139
|
+
// Pure functions for business logic
|
|
140
|
+
const increment = (): void => {
|
|
141
|
+
count += 1; // ✅ This is Svelte reactivity, not variable reassignment
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const addItem = (item: string): void => {
|
|
145
|
+
items = [...items, item]; // ✅ Immutable update
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const removeItem = (index: number): void => {
|
|
149
|
+
items = items.filter((_, i) => i !== index); // ✅ Immutable update
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
$effect(() => {
|
|
153
|
+
// Side effects here
|
|
154
|
+
console.log(`Count is: ${count}`);
|
|
155
|
+
});
|
|
156
|
+
</script>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Mandatory Checks Before Code Generation
|
|
160
|
+
|
|
161
|
+
1. **Immutability Check**: No direct mutation of objects/arrays (use spread, map, filter instead)
|
|
162
|
+
2. **Error Handling Check**: All possible errors must return Effect types, no throw statements
|
|
163
|
+
3. **TypeScript Check**: Proper TypeScript syntax, no JSDoc types, explicit return types
|
|
164
|
+
4. **Purity Check**: No side effects in pure functions, all dependencies explicit
|
|
165
|
+
5. **Svelte Context Check**: Use `let` only in Svelte components for reactive state, use `const` elsewhere
|
|
166
|
+
|
|
167
|
+
## Prohibited Patterns
|
|
168
|
+
|
|
169
|
+
- ❌ `throw new Error()` (use Effect types instead)
|
|
170
|
+
- ❌ Direct mutation: `array.push()`, `array.splice()`, `object.property = value`
|
|
171
|
+
- ❌ JSDoc `@type`, `@param`, `@return` annotations (use TypeScript syntax)
|
|
172
|
+
- ❌ `let` in pure TypeScript modules (use `const`)
|
|
173
|
+
- ❌ Class inheritance (`extends`) - prefer composition
|
|
174
|
+
|
|
175
|
+
## Required Patterns
|
|
176
|
+
|
|
177
|
+
- ✅ `let` + `$state<T>()` for Svelte component reactive state
|
|
178
|
+
- ✅ `const` for all variable declarations outside Svelte components
|
|
179
|
+
- ✅ `Effect<T, E>` from effect for error handling
|
|
180
|
+
- ✅ `map`, `filter`, `reduce` for iteration with immutable updates
|
|
181
|
+
- ✅ TypeScript interface/type definitions
|
|
182
|
+
- ✅ Pure functions with explicit return types
|
|
183
|
+
- ✅ Immutable updates to Svelte state: `array = [...array, newItem]`
|
|
184
|
+
|
|
185
|
+
## Context-Specific Rules
|
|
186
|
+
|
|
187
|
+
### In Svelte Components (.svelte files):
|
|
188
|
+
```typescript
|
|
189
|
+
// ✅ REQUIRED - Use let for reactive state
|
|
190
|
+
let count = $state<number>(0);
|
|
191
|
+
let user = $state<User | null>(null);
|
|
192
|
+
|
|
193
|
+
// ✅ Use const for helper functions
|
|
194
|
+
const calculateTotal = (items: readonly Item[]): number => {
|
|
195
|
+
return items.reduce((sum, item) => sum + item.price, 0);
|
|
196
|
+
};
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### In TypeScript Modules (.ts files):
|
|
200
|
+
```typescript
|
|
201
|
+
// ✅ REQUIRED - Use const for all declarations
|
|
202
|
+
import { Effect } from "effect";
|
|
203
|
+
|
|
204
|
+
export const DEFAULT_CONFIG = { theme: 'dark' } as const;
|
|
205
|
+
export const processData = (data: Data): Effect.Effect<Output, Error> => {
|
|
206
|
+
// Pure functional logic using Effect
|
|
207
|
+
return Effect.succeed(data);
|
|
208
|
+
};
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**Remember**: Functional programming principles are maintained through immutable data operations and pure functions, while respecting Svelte's reactive declaration patterns that require `let` for component state.
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## 🧠 Agent Instructions
|
|
4
|
+
|
|
5
|
+
You are OpenCode, an intelligent development agent specializing in TypeScript CLI tools and SvelteKit PWA project automation. Please read and adhere to the guidelines below.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
### 📌 Core Principles
|
|
10
|
+
|
|
11
|
+
- **Functional Programming Paradigm**: This project is built with functional programming at its core
|
|
12
|
+
- Use the **Effect library** (v3.19+) for all error handling
|
|
13
|
+
- Prefer pure functions with no side effects
|
|
14
|
+
- Use `Either.Either<Error, T>` for result types
|
|
15
|
+
- Leverage function composition and higher-order functions
|
|
16
|
+
- Maintain immutability and avoid direct mutation
|
|
17
|
+
- Separate pure business logic from I/O side effects
|
|
18
|
+
|
|
19
|
+
- **TypeScript Strict Mode**:
|
|
20
|
+
- Always use explicit types (no implicit any)
|
|
21
|
+
- Enable strict type-checking (`strict: true` in tsconfig.json)
|
|
22
|
+
- Leverage interfaces and type aliases for clarity
|
|
23
|
+
- Use `.ts` or `.mts` extensions for all new files
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
### 💻 Execution Environment
|
|
28
|
+
|
|
29
|
+
- **OS**: Windows 11
|
|
30
|
+
- **Shell**: Windows PowerShell
|
|
31
|
+
- **Node.js**: v24.x (latest LTS with built-in TypeScript support)
|
|
32
|
+
- **Package Manager**: pnpm v10.21.0
|
|
33
|
+
- **TypeScript**: v5.9.3
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
### 📦 Project Context
|
|
38
|
+
|
|
39
|
+
This is **pwa-sv**, a CLI tool that automates the creation of type-safe Progressive Web App (PWA) projects using SvelteKit.
|
|
40
|
+
|
|
41
|
+
**Key Modules**:
|
|
42
|
+
- `cli.ts`: Command-line interface using Commander.js
|
|
43
|
+
- `engine.ts`: Core automation pipeline with Effect-based error handling
|
|
44
|
+
- `deps-manager.ts`: Dependency installation using pnpm and execa
|
|
45
|
+
- `process-fs-handler.ts`: File system operations and SvelteKit project creation
|
|
46
|
+
|
|
47
|
+
**Architecture Pattern**: Pipeline/Filter with transactional integrity
|
|
48
|
+
- Each step in the pipeline returns `Either.Either<void, Error>`
|
|
49
|
+
- Failed steps trigger automatic rollback
|
|
50
|
+
- Pipeline state is tracked immutably
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### ✅ Best Practices
|
|
55
|
+
|
|
56
|
+
#### Code Style
|
|
57
|
+
- Use Effect library for all error handling (never use try/catch directly)
|
|
58
|
+
- Functions should return `Either.Either<T, Error>` for operations that can fail
|
|
59
|
+
- Use `Either.isLeft()` and `Either.isRight()` to check results
|
|
60
|
+
- Prefer `Effect.runPromise()` or `Either.match()` for result handling
|
|
61
|
+
- Keep functions small and focused (single responsibility)
|
|
62
|
+
- Use const declarations and immutable data structures
|
|
63
|
+
- Prefer expressions over statements
|
|
64
|
+
|
|
65
|
+
#### Testing
|
|
66
|
+
- Write tests using Vitest (configured in the project)
|
|
67
|
+
- Create test files alongside source files: `[module-name].test.ts`
|
|
68
|
+
- Test pure functions in isolation
|
|
69
|
+
- Mock I/O operations for integration tests
|
|
70
|
+
|
|
71
|
+
#### CLI Development
|
|
72
|
+
- Use Commander.js for CLI interface
|
|
73
|
+
- Validate user input before processing
|
|
74
|
+
- Provide helpful error messages
|
|
75
|
+
- Use `chalk` for colored console output (already configured)
|
|
76
|
+
|
|
77
|
+
#### Dependency Management
|
|
78
|
+
- Always use pnpm for package management
|
|
79
|
+
- Categorize dependencies as runtime or dev dependencies
|
|
80
|
+
- Use `execa` for running external commands
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
### 🚫 Do Not
|
|
85
|
+
|
|
86
|
+
- Use untyped JavaScript - always use TypeScript
|
|
87
|
+
- Use try/catch blocks for error handling - use Effect library instead
|
|
88
|
+
- Mutate function parameters or external state
|
|
89
|
+
- Use global variables or shared mutable state
|
|
90
|
+
- Install dependencies globally - use pnpm project-local
|
|
91
|
+
- Use `var` declarations - use `const` only
|
|
92
|
+
- Assume external tools are globally installed
|
|
93
|
+
- Write code that directly mutates the file system - use Effect-wrapped operations
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
### 🛠️ Common Patterns
|
|
98
|
+
|
|
99
|
+
#### Error Handling with Effect
|
|
100
|
+
```typescript
|
|
101
|
+
import { Either } from 'effect';
|
|
102
|
+
|
|
103
|
+
export const someOperation = async (input: string): Promise<Either.Either<Error, void>> => {
|
|
104
|
+
try {
|
|
105
|
+
// Pure logic here
|
|
106
|
+
return Either.right(void 0);
|
|
107
|
+
} catch (error: any) {
|
|
108
|
+
return Either.left(new Error(`Operation failed: ${error.message}`));
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### Pipeline Step Pattern
|
|
114
|
+
```typescript
|
|
115
|
+
const stepResult = await someOperation(config);
|
|
116
|
+
if (Either.isLeft(stepResult)) {
|
|
117
|
+
await performRollback(state);
|
|
118
|
+
return stepResult;
|
|
119
|
+
}
|
|
120
|
+
state.stepCompleted = true;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### 📁 File Organization
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
src/
|
|
129
|
+
├── cli.ts # CLI entry point (Commander.js)
|
|
130
|
+
├── engine.ts # Pipeline orchestration
|
|
131
|
+
├── deps-manager.ts # Dependency operations
|
|
132
|
+
├── process-fs-handler.ts # FS operations
|
|
133
|
+
└── types.ts # TypeScript interfaces
|
|
134
|
+
|
|
135
|
+
tests/ # Vitest test files
|
|
136
|
+
docs/ # Architecture documentation
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
Follow these guidelines to maintain functional purity, type safety, and compatibility with the pwa-sv CLI tool architecture.
|
package/README.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# pwa-sv - Svelte PWA Project Automation Tool
|
|
2
|
+
|
|
3
|
+
A CLI tool that streamlines the creation of typesafe Progressive Web App (PWA) projects using SvelteKit with a simple `pnpm create pwa-sv` command.
|
|
4
|
+
|
|
5
|
+
 │
|
|
6
|
+
│ 
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- **Quick Setup**: Create a SvelteKit PWA project with a single command
|
|
11
|
+
- **PWA Ready**: Pre-configured with service worker, manifest, and caching strategies
|
|
12
|
+
- **Vite Integration**: Properly configured PWA plugin for Vite
|
|
13
|
+
- **Package Scripts**: Pre-configured development, build, and preview scripts
|
|
14
|
+
- **Functional Programming Ready**: Includes [Effect](https://effect.website/) library and functional programming patterns
|
|
15
|
+
- **Type-Safe Error Handling**: Uses Effect's powerful error handling capabilities (with compatibility for existing Result patterns)
|
|
16
|
+
- **Optional Features**:
|
|
17
|
+
- Skeleton UI Framework (with `--skeleton` or `-s` flag)
|
|
18
|
+
- Internationalization Support (with `--i18n` or `-i` flag)
|
|
19
|
+
- Dexie IndexedDB Wrapper (with `--dexie` or `-d` flag)
|
|
20
|
+
- Playwright Browser Testing (with `--playwright` or `-p` flag)
|
|
21
|
+
|
|
22
|
+
## Installation & Usage
|
|
23
|
+
|
|
24
|
+
### Creating a New Project
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pnpm create pwa-sv my-pwa-project
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Using Command-Line Flags
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Create project with Skeleton UI
|
|
34
|
+
pnpm create pwa-sv my-pwa-project --skeleton
|
|
35
|
+
# Or using short flag
|
|
36
|
+
pnpm create pwa-sv my-pwa-project -s
|
|
37
|
+
|
|
38
|
+
# Create project with internationalization support
|
|
39
|
+
pnpm create pwa-sv my-pwa-project --i18n
|
|
40
|
+
# Or using short flag
|
|
41
|
+
pnpm create pwa-sv my-pwa-project -i
|
|
42
|
+
|
|
43
|
+
# Create project with Dexie for IndexedDB
|
|
44
|
+
pnpm create pwa-sv my-pwa-project --dexie
|
|
45
|
+
# Or using short flag
|
|
46
|
+
pnpm create pwa-sv my-pwa-project -d
|
|
47
|
+
|
|
48
|
+
# Create project with Playwright browser testing
|
|
49
|
+
pnpm create pwa-sv my-pwa-project --playwright
|
|
50
|
+
# Or using short flag
|
|
51
|
+
pnpm create pwa-sv my-pwa-project -p
|
|
52
|
+
|
|
53
|
+
# Create project with multiple optional features
|
|
54
|
+
pnpm create pwa-sv my-pwa-project --skeleton --i18n --dexie --playwright
|
|
55
|
+
|
|
56
|
+
# Use non-interactive mode (accept all defaults)
|
|
57
|
+
pnpm create pwa-sv my-pwa-project --yes
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Additional Options
|
|
61
|
+
|
|
62
|
+
- **Playwright Testing**: By default, Playwright is not installed. Use the `--playwright` (or `-p`) flag to include Playwright browser testing in your project.
|
|
63
|
+
- **Vitest Defaults**: When unit or component testing is selected, the `--defaults` flag is automatically used to bypass interactive prompts and automatically select both unit and component testing.
|
|
64
|
+
|
|
65
|
+
## Available Scripts
|
|
66
|
+
|
|
67
|
+
After project creation, these scripts are available in your `package.json`:
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
- `pnpm build-pwa-assets`: Generate PWA icons and assets
|
|
71
|
+
- `pnpm i18n:extract`: Extract translation keys (if i18n enabled)
|
|
72
|
+
- `pnpm i18n:check`: Check for missing translations (if i18n enabled)
|
|
73
|
+
|
|
74
|
+
## Project Structure
|
|
75
|
+
|
|
76
|
+
The generated project follows SvelteKit conventions with additional PWA-specific configurations:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
my-pwa-project/
|
|
80
|
+
├── package.json # Scripts and dependencies configured
|
|
81
|
+
|
|
82
|
+
├── vite.config.ts # Vite config with PWA plugin
|
|
83
|
+
├── svelte.config.js # SvelteKit configuration
|
|
84
|
+
├── tailwind.config.cjs # Tailwind CSS with Skeleton UI (if enabled)
|
|
85
|
+
├── src/ # SvelteKit application code
|
|
86
|
+
│ ├── lib/ # Reusable components, modules, etc.
|
|
87
|
+
│ │ ├── i18n/ # Internationalization config (if enabled)
|
|
88
|
+
│ │ └── locales/ # Translation files (if enabled)
|
|
89
|
+
│ ├── routes/ # Page routes
|
|
90
|
+
│ └── app.html # Application shell
|
|
91
|
+
├── static/ # Static assets directory
|
|
92
|
+
└── Configuration files (tsconfig.json, etc.)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Configuration
|
|
96
|
+
|
|
97
|
+
#### PWA Configuration
|
|
98
|
+
|
|
99
|
+
The `vite.config.ts` file includes the PWA plugin with service worker and manifest configuration. The manifest is automatically configured with default values.
|
|
100
|
+
|
|
101
|
+
## Internationalization (i18n)
|
|
102
|
+
|
|
103
|
+
When the `--i18n` flag is used, the project includes:
|
|
104
|
+
|
|
105
|
+
- `svelte-i18n` for internationalization
|
|
106
|
+
- Pre-configured English and Spanish locale files
|
|
107
|
+
- A sample component showing how to use translations
|
|
108
|
+
- Scripts for extracting and checking translations
|
|
109
|
+
|
|
110
|
+
## Skeleton UI
|
|
111
|
+
|
|
112
|
+
When the `--skeleton` flag is used, the project includes:
|
|
113
|
+
|
|
114
|
+
- Tailwind CSS configured with Skeleton UI
|
|
115
|
+
- Proper component aliases
|
|
116
|
+
- A sample component showing how to use Skeleton UI components
|
|
117
|
+
|
|
118
|
+
## Functional Programming Features
|
|
119
|
+
|
|
120
|
+
The generated SvelteKit PWA projects now include support for functional programming patterns using the [Effect](https://effect.website/) library. This provides:
|
|
121
|
+
|
|
122
|
+
- **Type-safe error handling** with Effect's powerful error management
|
|
123
|
+
- **Resource management** with automatic cleanup capabilities
|
|
124
|
+
- **Concurrent operations** with Effect's concurrency model
|
|
125
|
+
- **Effectful computations** with proper handling of side effects
|
|
126
|
+
- **Development tools** with integrated Effect Platform for comprehensive utilities
|
|
127
|
+
- **Backwards compatibility** with existing Result patterns
|
|
128
|
+
|
|
129
|
+
For more details on using functional programming in your generated applications, see the [functional programming documentation](./docs/functional-programming.md).
|
|
130
|
+
|
|
131
|
+
## Contributing
|
|
132
|
+
|
|
133
|
+
Contributions are welcome! This project was created using a comprehensive development workflow based on user stories and epics to ensure a well-architected, maintainable codebase.
|
|
134
|
+
|
|
135
|
+
## Publishing
|
|
136
|
+
|
|
137
|
+
To publish this CLI tool to npm as `pwa-sv`, please follow the steps in the [publishing guide](./docs/publishing-guide.md).
|
|
138
|
+
|
|
139
|
+
## Recent Changes
|
|
140
|
+
|
|
141
|
+
### Migration to Effect Library
|
|
142
|
+
The CLI tool has been updated to use the [Effect](https://effect.website/) library instead of neverthrow for functional programming patterns. This provides:
|
|
143
|
+
|
|
144
|
+
- More powerful functional programming capabilities
|
|
145
|
+
- Better resource management
|
|
146
|
+
- Enhanced error handling
|
|
147
|
+
- Compatibility with existing code
|
|
148
|
+
|
|
149
|
+
See the [migration documentation](./docs/migration.md) for more details.
|
|
150
|
+
|
|
151
|
+
### GitLab CI/CD Integration
|
|
152
|
+
Added comprehensive GitLab CI/CD configuration for automated testing, building, and publishing:
|
|
153
|
+
|
|
154
|
+
- Automated testing on every push and merge request
|
|
155
|
+
- Build verification and artifact storage
|
|
156
|
+
- Automated publishing to npm registries
|
|
157
|
+
- Documentation deployment
|
|
158
|
+
|
|
159
|
+
See the [publishing guide](./docs/publishing-guide.md) for more information.
|
|
160
|
+
|
|
161
|
+
## Package Information
|
|
162
|
+
|
|
163
|
+
This tool is published as [`pwa-sv`](https://www.npmjs.com/package/pwa-sv) on npm. Install it using:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
pnpm create pwa-sv my-project
|
|
167
|
+
# or
|
|
168
|
+
npm create pwa-sv my-project
|
|
169
|
+
# or
|
|
170
|
+
yarn create pwa-sv my-project
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## About EduTherapy
|
|
174
|
+
|
|
175
|
+
This tool is developed by **EduTherapy** (a brand of Talim Shifa Studio), specializing in digital transformation for education and healthcare sectors through Progressive Web Apps.
|
|
176
|
+
|
|
177
|
+
- 🌐 Website: https://eduth.pro/
|
|
178
|
+
- 📧 Contact: edutherapystudio@gmail.com
|
|
179
|
+
|
|
180
|
+
## License
|
|
181
|
+
|
|
182
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,KAAG,MAiBlD,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { createProject } from './engine.js';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
const program = new Command();
|
|
5
|
+
// Validate project name to ensure it's a valid directory name
|
|
6
|
+
export const validateProjectName = (name) => {
|
|
7
|
+
if (!name) {
|
|
8
|
+
throw new Error('Project name is required');
|
|
9
|
+
}
|
|
10
|
+
// Check for invalid characters in directory name
|
|
11
|
+
const invalidChars = /[<>:"/\\|?*]/g;
|
|
12
|
+
if (invalidChars.test(name)) {
|
|
13
|
+
throw new Error('Project name contains invalid characters');
|
|
14
|
+
}
|
|
15
|
+
// Check for valid NPM package name (simplified)
|
|
16
|
+
if (name.startsWith('.') || name.startsWith('_')) {
|
|
17
|
+
throw new Error('Project name cannot start with "." or "_"');
|
|
18
|
+
}
|
|
19
|
+
return name;
|
|
20
|
+
};
|
|
21
|
+
// Define the main command
|
|
22
|
+
program
|
|
23
|
+
.name('pwa-sv')
|
|
24
|
+
.description('CLI tool to create SvelteKit PWA projects')
|
|
25
|
+
.version('1.3.0')
|
|
26
|
+
.argument('<project-name>', 'Name of the project to create')
|
|
27
|
+
.option('--yes', 'Skip confirmation prompts (CI/CD mode)')
|
|
28
|
+
.option('-d, --dexie', 'Include Dexie IndexedDB wrapper')
|
|
29
|
+
.option('-s, --skeleton', 'Add Skeleton UI framework')
|
|
30
|
+
.option('-i, --i18n', 'Add internationalization support')
|
|
31
|
+
.option('-p, --playwright', 'Add Playwright for browser testing')
|
|
32
|
+
.action(async (rawProjectName, options) => {
|
|
33
|
+
try {
|
|
34
|
+
// Validate project name
|
|
35
|
+
const projectName = validateProjectName(rawProjectName);
|
|
36
|
+
// Check if directory already exists and non-interactive mode is on
|
|
37
|
+
if (options.yes && existsSync(projectName)) {
|
|
38
|
+
console.log(`Warning: Directory ${projectName} already exists and will be overwritten.`);
|
|
39
|
+
}
|
|
40
|
+
const config = {
|
|
41
|
+
projectName,
|
|
42
|
+
useDexie: options.dexie || false,
|
|
43
|
+
useSkeleton: options.skeleton || false,
|
|
44
|
+
useI18n: options.i18n || false,
|
|
45
|
+
usePlaywright: options.playwright || false,
|
|
46
|
+
nonInteractive: options.yes || false,
|
|
47
|
+
};
|
|
48
|
+
await createProject(config);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error('Error creating project:', error.message);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Add help option
|
|
56
|
+
program.showHelpAfterError('(add --help for additional information)');
|
|
57
|
+
program.parse();
|
|
58
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAEhC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,8DAA8D;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,iDAAiD;IACjD,MAAM,YAAY,GAAG,eAAe,CAAC;IACrC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,gDAAgD;IAChD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,0BAA0B;AAC1B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,2CAA2C,CAAC;KACxD,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,gBAAgB,EAAE,+BAA+B,CAAC;KAC3D,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC;KACzD,MAAM,CAAC,aAAa,EAAE,iCAAiC,CAAC;KACxD,MAAM,CAAC,gBAAgB,EAAE,2BAA2B,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,kCAAkC,CAAC;KACxD,MAAM,CAAC,kBAAkB,EAAE,oCAAoC,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,cAAsB,EAAE,OAAY,EAAE,EAAE;IACrD,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,WAAW,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;QAExD,mEAAmE;QACnE,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,sBAAsB,WAAW,0CAA0C,CAAC,CAAC;QAC3F,CAAC;QAED,MAAM,MAAM,GAAY;YACtB,WAAW;YACX,QAAQ,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK;YAChC,WAAW,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;YACtC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;YAC9B,aAAa,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;YAC1C,cAAc,EAAE,OAAO,CAAC,GAAG,IAAI,KAAK;SACrC,CAAC;QAEF,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,kBAAkB;AAClB,OAAO,CAAC,kBAAkB,CAAC,yCAAyC,CAAC,CAAC;AACtE,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deps-manager.d.ts","sourceRoot":"","sources":["../src/deps-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAkBhC;;;;GAIG;AACH,QAAA,MAAM,mBAAmB,GAAI,QAAQ,OAAO,KAAG,MAAM,EA8BpD,CAAC;AAEF;;;;GAIG;AACH,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM,MAAM,EAAE,KAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,EAAE,CAAA;CAsBjG,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAU,QAAQ,OAAO,KAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAsC7F,CAAC"}
|