@swoff/cli 0.3.12 → 0.3.14
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 +32 -30
- package/dist/index.js +2 -32
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/help.js +6 -16
- package/dist/lib/cli/help.js.map +1 -1
- package/dist/lib/cli/logger.js +1 -0
- package/dist/lib/cli/logger.js.map +1 -1
- package/dist/lib/commands/add.js +29 -87
- package/dist/lib/commands/add.js.map +1 -1
- package/dist/lib/commands/assets.js +11 -4
- package/dist/lib/commands/assets.js.map +1 -1
- package/dist/lib/commands/clean.js +2 -10
- package/dist/lib/commands/clean.js.map +1 -1
- package/dist/lib/commands/generate-guide.js +16 -30
- package/dist/lib/commands/generate-guide.js.map +1 -1
- package/dist/lib/commands/generate.js +55 -58
- package/dist/lib/commands/generate.js.map +1 -1
- package/dist/lib/commands/init.js +187 -31
- package/dist/lib/commands/init.js.map +1 -1
- package/dist/lib/commands/validate.js +2 -4
- package/dist/lib/commands/validate.js.map +1 -1
- package/dist/lib/config/loader.js +34 -25
- package/dist/lib/config/loader.js.map +1 -1
- package/dist/lib/config/validator.js +210 -89
- package/dist/lib/config/validator.js.map +1 -1
- package/dist/lib/generators/file-generators/api-config.js +1 -1
- package/dist/lib/generators/file-generators/api-config.js.map +1 -1
- package/dist/lib/generators/file-generators/auth-adapter.js +13 -0
- package/dist/lib/generators/file-generators/auth-adapter.js.map +1 -0
- package/dist/lib/generators/file-generators/auth-check.js +40 -0
- package/dist/lib/generators/file-generators/auth-check.js.map +1 -0
- package/dist/lib/generators/file-generators/auth-store.js +2 -5
- package/dist/lib/generators/file-generators/auth-store.js.map +1 -1
- package/dist/lib/generators/file-generators/background-sync.js +1 -1
- package/dist/lib/generators/file-generators/background-sync.js.map +1 -1
- package/dist/lib/generators/file-generators/cache.js +2 -1
- package/dist/lib/generators/file-generators/cache.js.map +1 -1
- package/dist/lib/generators/file-generators/client-injector-bundle.js +15 -0
- package/dist/lib/generators/file-generators/client-injector-bundle.js.map +1 -0
- package/dist/lib/generators/file-generators/client-injector.js +2 -1
- package/dist/lib/generators/file-generators/client-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/connectivity-manager.js +12 -0
- package/dist/lib/generators/file-generators/connectivity-manager.js.map +1 -0
- package/dist/lib/generators/file-generators/connectivity.js +12 -0
- package/dist/lib/generators/file-generators/connectivity.js.map +1 -0
- package/dist/lib/generators/file-generators/context.js +7 -0
- package/dist/lib/generators/file-generators/context.js.map +1 -1
- package/dist/lib/generators/file-generators/fetch-wrapper.js +1 -1
- package/dist/lib/generators/file-generators/fetch-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/generate-framework-adapters.js +29 -23
- package/dist/lib/generators/file-generators/generate-framework-adapters.js.map +1 -1
- package/dist/lib/generators/file-generators/gql-wrapper.js +2 -2
- package/dist/lib/generators/file-generators/gql-wrapper.js.map +1 -1
- package/dist/lib/generators/file-generators/guide-generator.js +57 -16
- package/dist/lib/generators/file-generators/guide-generator.js.map +1 -1
- package/dist/lib/generators/file-generators/invalidation-tags.js +2 -3
- package/dist/lib/generators/file-generators/invalidation-tags.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-queue.js +2 -2
- package/dist/lib/generators/file-generators/mutation-queue.js.map +1 -1
- package/dist/lib/generators/file-generators/mutation-state.js +1 -1
- package/dist/lib/generators/file-generators/mutation-state.js.map +1 -1
- package/dist/lib/generators/file-generators/notification-generator.js +6 -0
- package/dist/lib/generators/file-generators/notification-generator.js.map +1 -0
- package/dist/lib/generators/file-generators/open-db.js +6 -0
- package/dist/lib/generators/file-generators/open-db.js.map +1 -0
- package/dist/lib/generators/file-generators/push.js +1 -2
- package/dist/lib/generators/file-generators/push.js.map +1 -1
- package/dist/lib/generators/file-generators/pwa-install.js +2 -6
- package/dist/lib/generators/file-generators/pwa-install.js.map +1 -1
- package/dist/lib/generators/file-generators/server-push.js +1 -1
- package/dist/lib/generators/file-generators/server-push.js.map +1 -1
- package/dist/lib/generators/file-generators/storage-generator.js +6 -0
- package/dist/lib/generators/file-generators/storage-generator.js.map +1 -0
- package/dist/lib/generators/file-generators/storage-notify.js +6 -0
- package/dist/lib/generators/file-generators/storage-notify.js.map +1 -0
- package/dist/lib/generators/file-generators/storage.js +6 -0
- package/dist/lib/generators/file-generators/storage.js.map +1 -0
- package/dist/lib/generators/file-generators/sw-generator-build.js +96 -45
- package/dist/lib/generators/file-generators/sw-generator-build.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-injector.js +1 -4
- package/dist/lib/generators/file-generators/sw-injector.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-template.js +8 -9
- package/dist/lib/generators/file-generators/sw-template.js.map +1 -1
- package/dist/lib/generators/file-generators/sw-version-gen.js +32 -0
- package/dist/lib/generators/file-generators/sw-version-gen.js.map +1 -0
- package/dist/lib/generators/file-generators/swoff-api-bundle.js +51 -0
- package/dist/lib/generators/file-generators/swoff-api-bundle.js.map +1 -0
- package/dist/lib/generators/sw-build-utils.js +69 -0
- package/dist/lib/generators/sw-build-utils.js.map +1 -0
- package/dist/lib/generators/sw-generator.js +26 -45
- package/dist/lib/generators/sw-generator.js.map +1 -1
- package/dist/lib/generators/sw-sections/activate-handler.js +74 -23
- package/dist/lib/generators/sw-sections/activate-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/assemble-sw.js +15 -95
- package/dist/lib/generators/sw-sections/assemble-sw.js.map +1 -1
- package/dist/lib/generators/sw-sections/background-sync-handler.js +74 -72
- package/dist/lib/generators/sw-sections/background-sync-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/batch-refresh-queue.js +102 -0
- package/dist/lib/generators/sw-sections/batch-refresh-queue.js.map +1 -0
- package/dist/lib/generators/sw-sections/config-header.js +2 -3
- package/dist/lib/generators/sw-sections/config-header.js.map +1 -1
- package/dist/lib/generators/sw-sections/default-template.js +59 -6
- package/dist/lib/generators/sw-sections/default-template.js.map +1 -1
- package/dist/lib/generators/sw-sections/fetch-handler.js +621 -495
- package/dist/lib/generators/sw-sections/fetch-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/install-handler.js +40 -23
- package/dist/lib/generators/sw-sections/install-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/message-handler.js +25 -8
- package/dist/lib/generators/sw-sections/message-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/server-push-handler.js +10 -14
- package/dist/lib/generators/sw-sections/server-push-handler.js.map +1 -1
- package/dist/lib/generators/sw-sections/shared.js +68 -0
- package/dist/lib/generators/sw-sections/shared.js.map +1 -0
- package/dist/lib/generators/sw-sections/sw-push.js +2 -6
- package/dist/lib/generators/sw-sections/sw-push.js.map +1 -1
- package/dist/lib/generators/sw-sections/tag-management.js +55 -86
- package/dist/lib/generators/sw-sections/tag-management.js.map +1 -1
- package/dist/lib/generators/swoff-files-generator.js +185 -66
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +68 -72
- package/dist/lib/shared/config-types.js.map +1 -1
- package/dist/lib/shared/feature-registry.js +198 -0
- package/dist/lib/shared/feature-registry.js.map +1 -0
- package/dist/lib/utils/detect-framework.js +52 -9
- package/dist/lib/utils/detect-framework.js.map +1 -1
- package/dist/runtime/api-config.js +2 -2
- package/dist/runtime/api-config.js.map +1 -1
- package/dist/runtime/auth-adapter.js +179 -0
- package/dist/runtime/auth-adapter.js.map +1 -0
- package/dist/runtime/auth-state.js +16 -6
- package/dist/runtime/auth-state.js.map +1 -1
- package/dist/runtime/auth-store.js +219 -213
- package/dist/runtime/auth-store.js.map +1 -1
- package/dist/runtime/auth-user.js +5 -19
- package/dist/runtime/auth-user.js.map +1 -1
- package/dist/runtime/background-sync.js +5 -2
- package/dist/runtime/background-sync.js.map +1 -1
- package/dist/runtime/cache.js +91 -3
- package/dist/runtime/cache.js.map +1 -1
- package/dist/runtime/client-injector-bundle.js +314 -0
- package/dist/runtime/client-injector-bundle.js.map +1 -0
- package/dist/runtime/client-injector.js +173 -30
- package/dist/runtime/client-injector.js.map +1 -1
- package/dist/runtime/connectivity-manager.js +83 -0
- package/dist/runtime/connectivity-manager.js.map +1 -0
- package/dist/runtime/connectivity.js +83 -0
- package/dist/runtime/connectivity.js.map +1 -0
- package/dist/runtime/fetch-wrapper.js +26 -59
- package/dist/runtime/fetch-wrapper.js.map +1 -1
- package/dist/runtime/gql-wrapper.js +15 -9
- package/dist/runtime/gql-wrapper.js.map +1 -1
- package/dist/runtime/invalidation-tags.js +12 -89
- package/dist/runtime/invalidation-tags.js.map +1 -1
- package/dist/runtime/mutation-queue.js +83 -31
- package/dist/runtime/mutation-queue.js.map +1 -1
- package/dist/runtime/mutation-state.js +3 -3
- package/dist/runtime/mutation-state.js.map +1 -1
- package/dist/runtime/notification.js +65 -0
- package/dist/runtime/notification.js.map +1 -0
- package/dist/runtime/open-db.js +41 -0
- package/dist/runtime/open-db.js.map +1 -0
- package/dist/runtime/push.js +15 -27
- package/dist/runtime/push.js.map +1 -1
- package/dist/runtime/pwa-injector.js +3 -32
- package/dist/runtime/pwa-injector.js.map +1 -1
- package/dist/runtime/pwa-prompt.js +35 -3
- package/dist/runtime/pwa-prompt.js.map +1 -1
- package/dist/runtime/reset.js +39 -42
- package/dist/runtime/reset.js.map +1 -1
- package/dist/runtime/server-push.js +23 -13
- package/dist/runtime/server-push.js.map +1 -1
- package/dist/runtime/storage.js +32 -0
- package/dist/runtime/storage.js.map +1 -0
- package/dist/runtime/sw-injector.js +19 -178
- package/dist/runtime/sw-injector.js.map +1 -1
- package/dist/runtime/sw-version.js +13 -0
- package/dist/runtime/sw-version.js.map +1 -0
- package/dist/runtime/swoff-api-bundle.js +1491 -0
- package/dist/runtime/swoff-api-bundle.js.map +1 -0
- package/dist/runtime/type-definitions.js +8 -7
- package/dist/runtime/type-definitions.js.map +1 -1
- package/dist/runtime/utils.js +4 -0
- package/dist/runtime/utils.js.map +1 -1
- package/dist/swoff-nkdhhmw8. +18 -0
- package/dist/swoff.js +5 -0
- package/package.json +1 -3
- package/templates/react/useAuth.jsx +7 -4
- package/templates/react/useAuth.tsx +14 -14
- package/templates/react/useBackgroundSync.jsx +5 -4
- package/templates/react/useBackgroundSync.tsx +5 -4
- package/templates/react/useCachedFetch.jsx +8 -0
- package/templates/react/useCachedFetch.tsx +8 -0
- package/templates/react/useMutation.jsx +60 -56
- package/templates/react/useMutation.tsx +65 -64
- package/templates/react/useMutationQueue.jsx +5 -1
- package/templates/react/useMutationQueue.tsx +8 -2
- package/templates/react/useMutationState.jsx +3 -4
- package/templates/react/useMutationState.tsx +4 -8
- package/templates/react/useNetworkStatus.jsx +57 -17
- package/templates/react/useNetworkStatus.tsx +42 -20
- package/templates/react/useOfflineAnalytics.jsx +42 -0
- package/templates/react/useOfflineAnalytics.tsx +50 -0
- package/templates/react/usePwaInstall.jsx +26 -0
- package/templates/react/usePwaInstall.tsx +26 -0
- package/templates/react/useSWUpdate.jsx +7 -52
- package/templates/react/useSWUpdate.tsx +12 -51
- package/templates/react/useStorageEstimate.jsx +56 -0
- package/templates/react/useStorageEstimate.tsx +67 -0
- package/dist/__tests__/assemble-sw.test.js +0 -145
- package/dist/__tests__/assemble-sw.test.js.map +0 -1
- package/dist/__tests__/cli-integration.test.js +0 -231
- package/dist/__tests__/cli-integration.test.js.map +0 -1
- package/dist/__tests__/config-types.test.js +0 -124
- package/dist/__tests__/config-types.test.js.map +0 -1
- package/dist/__tests__/detect-language.test.js +0 -51
- package/dist/__tests__/detect-language.test.js.map +0 -1
- package/dist/__tests__/file-generators.test.js +0 -228
- package/dist/__tests__/file-generators.test.js.map +0 -1
- package/dist/__tests__/glob-matcher.test.js +0 -86
- package/dist/__tests__/glob-matcher.test.js.map +0 -1
- package/dist/__tests__/invalidation-tags.test.js +0 -283
- package/dist/__tests__/invalidation-tags.test.js.map +0 -1
- package/dist/__tests__/loader.test.js +0 -77
- package/dist/__tests__/loader.test.js.map +0 -1
- package/dist/__tests__/validator.test.js +0 -340
- package/dist/__tests__/validator.test.js.map +0 -1
- package/templates/react/useCacheInvalidation.jsx +0 -19
- package/templates/react/useCacheInvalidation.tsx +0 -52
- package/templates/react/useIsFetching.jsx +0 -32
- package/templates/react/useIsFetching.tsx +0 -32
package/README.md
CHANGED
|
@@ -2,20 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
CLI for [Swoff](https://swoff.netlify.app) — offline-first web apps made easy.
|
|
4
4
|
|
|
5
|
-
Swoff generates a **service worker** and **client
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Swoff generates a **service worker** and **client utilities** from a config file — zero runtime
|
|
6
|
+
dependencies, no Workbox, all auditable code. Server-state reactivity, offline queues, PWA install,
|
|
7
|
+
push notifications, auth, and cross-tab sync — out of the box.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npx @swoff/cli init # create swoff.config.json
|
|
11
|
-
npx @swoff/cli generate # generate
|
|
11
|
+
npx @swoff/cli generate # generate swoff/ files
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
### With a bundler (React, Next.js, Vue, Svelte, Astro)
|
|
15
15
|
|
|
16
16
|
```js
|
|
17
|
-
import {
|
|
18
|
-
|
|
17
|
+
import { fetchWithCache } from "./swoff/fetch/core";
|
|
18
|
+
const { response } = await fetchWithCache("/api/todos");
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Without a bundler (vanilla, Laravel, Django, Rails, Go)
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<script src="/swoff/client-injector.bundle.js"></script>
|
|
25
|
+
<script src="/swoff/swoff-api.bundle.js"></script>
|
|
26
|
+
<script>
|
|
27
|
+
swoff.fetchWithCache("/api/todos").then((r) => r.json());
|
|
28
|
+
</script>
|
|
19
29
|
```
|
|
20
30
|
|
|
21
31
|
## Features
|
|
@@ -42,36 +52,28 @@ initServiceWorker();
|
|
|
42
52
|
| ---------------- | ---------------------------------------------- |
|
|
43
53
|
| `init` | Create `swoff.config.json` with auto-detection |
|
|
44
54
|
| `generate` | Generate SW + all supporting files |
|
|
45
|
-
| `add <feature>` | Enable a feature and regenerate |
|
|
46
55
|
| `validate` | Validate `swoff.config.json` |
|
|
47
56
|
| `info [feature]` | Show summary or per-feature details |
|
|
48
57
|
| `clean` | Remove all generated files and config |
|
|
49
58
|
| `help [command]` | Show help for a specific command |
|
|
50
59
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Create `swoff.config.json` with `swoff init`, then tweak as needed.
|
|
54
|
-
Full schema reference in [docs/CONFIG.md](./docs/CONFIG.md).
|
|
55
|
-
|
|
56
|
-
## API Reference
|
|
57
|
-
|
|
58
|
-
Read the [API reference](./docs/API.md) for detailed information on each API.
|
|
59
|
-
|
|
60
|
-
## CLI Reference
|
|
60
|
+
For PWA asset generation (icons, splash screens, favicons, manifest.json), use the standalone [`@swoff/assets`](https://github.com/iamsuudi/swoff) package:
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
Read the [architecture](./docs/ARCHITECTURE.md) for detailed information on the project's architecture.
|
|
67
|
-
|
|
68
|
-
## Comparison With Other Popular Tools
|
|
69
|
-
|
|
70
|
-
Read the [comparison](./docs/COMPARISON.md) for a comprehensive comparison with popular tools.
|
|
71
|
-
|
|
72
|
-
## Ecosystem
|
|
62
|
+
```bash
|
|
63
|
+
npx @swoff/assets --source ./logo.svg
|
|
64
|
+
```
|
|
73
65
|
|
|
74
|
-
|
|
66
|
+
## Documentation
|
|
67
|
+
|
|
68
|
+
| Guide | Description |
|
|
69
|
+
| ---------------------------------------------------------------- | ------------------------------------------------- |
|
|
70
|
+
| [Config](https://swoff.netlify.app/docs/config) | Full config schema and feature reference |
|
|
71
|
+
| [API](https://swoff.netlify.app/docs/api) | Client API reference (auth, cache, mutations) |
|
|
72
|
+
| [CLI](https://swoff.netlify.app/docs/cli) | CLI commands and options |
|
|
73
|
+
| [Guides](https://swoff.netlify.app/docs/guides) | Step-by-step guides for each feature |
|
|
74
|
+
| [Architecture](https://swoff.netlify.app/docs/architecture) | Design decisions and rationale |
|
|
75
|
+
| [Comparison](https://swoff.netlify.app/docs/comparison) | Swoff vs Workbox / Serwist / SWR / TanStack Query |
|
|
76
|
+
| [Ecosystem](https://swoff.netlify.app/docs/frameworks/ecosystem) | Framework integration guides |
|
|
75
77
|
|
|
76
78
|
---
|
|
77
79
|
|
package/dist/index.js
CHANGED
|
@@ -7,9 +7,7 @@ import { showHelp } from "./lib/cli/help.js";
|
|
|
7
7
|
import { initCommand } from "./lib/commands/init.js";
|
|
8
8
|
import { generateCommand } from "./lib/commands/generate.js";
|
|
9
9
|
import { validateCommand } from "./lib/commands/validate.js";
|
|
10
|
-
import { addCommand } from "./lib/commands/add.js";
|
|
11
10
|
import { cleanCommand } from "./lib/commands/clean.js";
|
|
12
|
-
import { generateAssetsCommand } from "./lib/commands/assets.js";
|
|
13
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
14
12
|
const packageDir = join(__dirname, "..");
|
|
15
13
|
const projectRoot = process.cwd();
|
|
@@ -28,13 +26,8 @@ const { values, positionals } = parseArgs({
|
|
|
28
26
|
version: { type: "boolean", short: "v" },
|
|
29
27
|
help: { type: "boolean", short: "h" },
|
|
30
28
|
framework: { type: "string" },
|
|
31
|
-
"sw-only": { type: "boolean" },
|
|
32
|
-
"files-only": { type: "boolean" },
|
|
33
29
|
language: { type: "string" },
|
|
34
|
-
|
|
35
|
-
source: { type: "string" },
|
|
36
|
-
"output-dir": { type: "string" },
|
|
37
|
-
"no-splash": { type: "boolean" },
|
|
30
|
+
debug: { type: "boolean" },
|
|
38
31
|
yes: { type: "boolean", short: "y" },
|
|
39
32
|
},
|
|
40
33
|
allowPositionals: true,
|
|
@@ -55,35 +48,12 @@ async function main() {
|
|
|
55
48
|
break;
|
|
56
49
|
}
|
|
57
50
|
case "generate": {
|
|
58
|
-
await generateCommand(projectRoot, {
|
|
59
|
-
swOnly: !!values["sw-only"],
|
|
60
|
-
filesOnly: !!values["files-only"],
|
|
61
|
-
language: values.language,
|
|
62
|
-
continueOnSwError: !!values["continue-on-sw-error"],
|
|
63
|
-
});
|
|
51
|
+
await generateCommand(projectRoot, { language: values.language, debug: !!values.debug });
|
|
64
52
|
break;
|
|
65
53
|
}
|
|
66
54
|
case "validate":
|
|
67
55
|
await validateCommand(projectRoot);
|
|
68
56
|
break;
|
|
69
|
-
case "add": {
|
|
70
|
-
const feature = positionals.slice(1).join(",");
|
|
71
|
-
if (!feature) {
|
|
72
|
-
log.error("Please specify a feature to add");
|
|
73
|
-
log.info("Usage: swoff add <feature1>[,<feature2>,...]");
|
|
74
|
-
log.info("Features: mutation-queue, pwa, cross-tab, auth, tag-invalidation, background-sync, graphql, push-notification, htmx, php");
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
await addCommand(projectRoot, feature);
|
|
78
|
-
break;
|
|
79
|
-
}
|
|
80
|
-
case "assets":
|
|
81
|
-
await generateAssetsCommand(projectRoot, {
|
|
82
|
-
source: values.source,
|
|
83
|
-
outputDir: values["output-dir"],
|
|
84
|
-
noSplash: !!values["no-splash"],
|
|
85
|
-
});
|
|
86
|
-
break;
|
|
87
57
|
case "clean":
|
|
88
58
|
await cleanCommand(projectRoot, { yes: !!values.yes });
|
|
89
59
|
break;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/cli/help.js
CHANGED
|
@@ -6,31 +6,21 @@ import { log } from "./logger.js";
|
|
|
6
6
|
export const commands = {
|
|
7
7
|
init: {
|
|
8
8
|
description: "Initialize Swoff in current directory",
|
|
9
|
-
usage: "swoff init [--framework react|vue|svelte|vanilla]",
|
|
10
|
-
examples: ["swoff init", "swoff init --framework react"],
|
|
9
|
+
usage: "swoff init [--framework react-spa|nextjs|remix|tanstack-start-react|astro|nuxt|sveltekit|vue|svelte|vanilla]",
|
|
10
|
+
examples: ["swoff init", "swoff init --framework react-spa"],
|
|
11
11
|
},
|
|
12
12
|
generate: {
|
|
13
|
-
description: "Generate
|
|
14
|
-
usage: "swoff generate [--
|
|
15
|
-
examples: ["swoff generate"
|
|
13
|
+
description: "Generate supporting files (swoff/)",
|
|
14
|
+
usage: "swoff generate [--language ts|js]",
|
|
15
|
+
examples: ["swoff generate"],
|
|
16
16
|
},
|
|
17
17
|
validate: {
|
|
18
18
|
description: "Validate swoff.config.json",
|
|
19
19
|
usage: "swoff validate",
|
|
20
20
|
examples: ["swoff validate"],
|
|
21
21
|
},
|
|
22
|
-
add: {
|
|
23
|
-
description: "Add specific feature files (mutation-queue, pwa, cross-tab, auth, background-sync, graphql, push-notification, htmx, php)",
|
|
24
|
-
usage: "swoff add <feature1>[,<feature2>,...]",
|
|
25
|
-
examples: ["swoff add pwa", "swoff add auth,graphql", "swoff add htmx"],
|
|
26
|
-
},
|
|
27
|
-
assets: {
|
|
28
|
-
description: "Generate PWA assets (icons, favicon, OG image, splash screens) from source image",
|
|
29
|
-
usage: "swoff assets --source <path> [--no-splash]",
|
|
30
|
-
examples: ["swoff assets --source ./logo.svg", "swoff assets --source ./logo.svg --no-splash"],
|
|
31
|
-
},
|
|
32
22
|
clean: {
|
|
33
|
-
description: "Remove Swoff from the project (swoff/, config
|
|
23
|
+
description: "Remove Swoff from the project (swoff/, config). Use --yes to skip confirmation",
|
|
34
24
|
usage: "swoff clean [--yes|-y]",
|
|
35
25
|
examples: ["swoff clean", "swoff clean --yes"],
|
|
36
26
|
},
|
package/dist/lib/cli/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/lib/cli/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAQlC,MAAM,CAAC,MAAM,QAAQ,GAA+B;IAClD,IAAI,EAAE;QACJ,WAAW,EAAE,uCAAuC;QACpD,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../../src/lib/cli/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAQlC,MAAM,CAAC,MAAM,QAAQ,GAA+B;IAClD,IAAI,EAAE;QACJ,WAAW,EAAE,uCAAuC;QACpD,KAAK,EAAE,8GAA8G;QACrH,QAAQ,EAAE,CAAC,YAAY,EAAE,kCAAkC,CAAC;KAC7D;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,oCAAoC;QACjD,KAAK,EAAE,mCAAmC;QAC1C,QAAQ,EAAE,CAAC,gBAAgB,CAAC;KAC7B;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,4BAA4B;QACzC,KAAK,EAAE,gBAAgB;QACvB,QAAQ,EAAE,CAAC,gBAAgB,CAAC;KAC7B;IACD,KAAK,EAAE;QACL,WAAW,EAAE,gFAAgF;QAC7F,KAAK,EAAE,wBAAwB;QAC/B,QAAQ,EAAE,CAAC,aAAa,EAAE,mBAAmB,CAAC;KAC/C;IACD,IAAI,EAAE;QACJ,WAAW,EAAE,uBAAuB;QACpC,KAAK,EAAE,sBAAsB;QAC7B,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC5C;CACF,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,WAAoB;IAC3C,IAAI,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClC,GAAG,CAAC,MAAM,CAAC,SAAS,WAAW,UAAU,CAAC,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,QAAQ,MAAM,CAAC,KAAK,uCAAuC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,IAAI,4BAA4B,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QACvF,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,SAAS,MAAM,CAAC,IAAI,uBAAuB,MAAM,CAAC,KAAK,0CAA0C,CAAC,CAAC;IACjH,CAAC;AACH,CAAC"}
|
package/dist/lib/cli/logger.js
CHANGED
|
@@ -10,5 +10,6 @@ export const log = {
|
|
|
10
10
|
help: (msg) => console.log(`${colors.cyan}${msg}${colors.reset}`),
|
|
11
11
|
header: (msg) => console.log(`${colors.bright}${msg}${colors.reset}`),
|
|
12
12
|
normal: (msg) => console.log(`${colors.reset}${msg}${colors.reset}`),
|
|
13
|
+
dim: (msg) => console.log(`${colors.dim}${msg}${colors.reset}`),
|
|
13
14
|
};
|
|
14
15
|
//# sourceMappingURL=logger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/lib/cli/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzE,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CACvB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACvD,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CACpB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC3E,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzE,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7E,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/lib/cli/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzE,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CACvB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACvD,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CACpB,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,KAAK,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC3E,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IACzE,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC7E,MAAM,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5E,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;CACxE,CAAC"}
|
package/dist/lib/commands/add.js
CHANGED
|
@@ -2,119 +2,61 @@
|
|
|
2
2
|
* add command - enables one or more feature flags and regenerates.
|
|
3
3
|
* Supports comma-separated features: swoff add auth,graphql,pwa
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { join
|
|
7
|
-
import { fileURLToPath } from "url";
|
|
5
|
+
import { writeFileSync } from "fs";
|
|
6
|
+
import { join } from "path";
|
|
8
7
|
import { log } from "../cli/logger.js";
|
|
9
8
|
import { loadConfigAsync } from "../config/loader.js";
|
|
10
|
-
import {
|
|
9
|
+
import { deepMerge } from "../shared/config-types.js";
|
|
10
|
+
import { FEATURES, resolveDependencies, getAuthConflicts, buildConfigUpdate } from "../shared/feature-registry.js";
|
|
11
11
|
import { generateCommand } from "./generate.js";
|
|
12
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
-
const templatesDir = join(__dirname, "../../../../templates");
|
|
14
12
|
const FEATURE_ALIASES = {
|
|
15
13
|
mutationqueue: "mutation-queue",
|
|
16
|
-
crosstab: "cross-tab",
|
|
17
14
|
backgroundsync: "background-sync",
|
|
18
15
|
pushnotification: "push-notification",
|
|
19
16
|
};
|
|
20
|
-
const FEATURE_NAMES =
|
|
21
|
-
"mutation-queue", "pwa", "cross-tab", "auth",
|
|
22
|
-
"background-sync", "graphql", "push-notification",
|
|
23
|
-
"htmx", "php",
|
|
24
|
-
];
|
|
25
|
-
const FEATURE_CONFIG_UPDATES = {
|
|
26
|
-
"mutation-queue": { mutationQueue: { enabled: true, batchSize: 1, batchDelayMs: 0, maxRetries: 5, retryBackoffMs: 1000 } },
|
|
27
|
-
pwa: { pwa: { enabled: true } },
|
|
28
|
-
"cross-tab": { crossTabSync: true },
|
|
29
|
-
auth: { auth: { enabled: true, type: "bearer", refreshPath: "/api/refresh", userEndpoint: "/api/me" } },
|
|
30
|
-
"background-sync": { backgroundSync: true },
|
|
31
|
-
graphql: { graphql: { enabled: true, endpoint: "/graphql" } },
|
|
32
|
-
"push-notification": { pushNotifications: { enabled: true, vapidPublicKey: "" } },
|
|
33
|
-
htmx: {},
|
|
34
|
-
php: {},
|
|
35
|
-
};
|
|
17
|
+
const FEATURE_NAMES = Object.keys(FEATURES);
|
|
36
18
|
function normalizeFeature(name) {
|
|
37
19
|
const lower = name.toLowerCase().trim();
|
|
38
20
|
return FEATURE_ALIASES[lower] ?? lower;
|
|
39
21
|
}
|
|
40
|
-
function mergeFeatureIntoRaw(raw, update) {
|
|
41
|
-
const features = { ...(raw.features || {}) };
|
|
42
|
-
for (const [key, value] of Object.entries(update)) {
|
|
43
|
-
if (typeof value === "object" && value !== null && typeof features[key] === "object" && features[key] !== null) {
|
|
44
|
-
features[key] = { ...features[key], ...value };
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
features[key] = value;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return { ...raw, features };
|
|
51
|
-
}
|
|
52
22
|
export async function addCommand(projectRoot, featureArg) {
|
|
53
|
-
const
|
|
54
|
-
const
|
|
23
|
+
const rawFeatures = featureArg.split(",").map(normalizeFeature).filter(Boolean);
|
|
24
|
+
const coreFeatures = rawFeatures;
|
|
25
|
+
const invalid = coreFeatures.filter((f) => !FEATURES[f]);
|
|
55
26
|
if (invalid.length > 0) {
|
|
56
27
|
log.error(`Unknown feature(s): ${invalid.join(", ")}`);
|
|
57
28
|
log.info(`Available: ${FEATURE_NAMES.join(", ")}`);
|
|
58
29
|
return;
|
|
59
30
|
}
|
|
60
|
-
const label =
|
|
31
|
+
const label = rawFeatures.length === 1 ? rawFeatures[0] : `${rawFeatures.length} features`;
|
|
61
32
|
log.header(`Adding ${label}`);
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
const
|
|
33
|
+
const loadResult = await loadConfigAsync(projectRoot);
|
|
34
|
+
const configPath = loadResult.configPath;
|
|
35
|
+
const existingConfig = loadResult.config;
|
|
36
|
+
const deps = resolveDependencies(coreFeatures);
|
|
37
|
+
const authConflicts = getAuthConflicts(deps, existingConfig);
|
|
38
|
+
if (authConflicts.length > 0) {
|
|
39
|
+
log.error(`Cannot add ${authConflicts.join(", ")} with auth type "${existingConfig.features.auth.type}" — these features require cookie auth`);
|
|
40
|
+
log.info("Change auth type to \"cookie\" in swoff.config.json and try again, or run: swoff add auth");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const combinedUpdate = buildConfigUpdate(coreFeatures);
|
|
44
|
+
let mergedConfig = deepMerge(existingConfig, { features: combinedUpdate });
|
|
45
|
+
const isJsConfig = configPath ? configPath.endsWith(".js") : false;
|
|
46
|
+
const resolvedConfigPath = (!configPath || isJsConfig)
|
|
47
|
+
? join(projectRoot, "swoff.config.json")
|
|
48
|
+
: configPath;
|
|
66
49
|
if (!configPath) {
|
|
67
50
|
log.warn("No config found. Creating new config with features...");
|
|
68
|
-
const newConfig = {
|
|
69
|
-
...defaultConfig,
|
|
70
|
-
$schema: "https://swoff.netlify.app/schema/v1.json",
|
|
71
|
-
features: {
|
|
72
|
-
...defaultConfig.features,
|
|
73
|
-
serviceWorker: {
|
|
74
|
-
...defaultConfig.features.serviceWorker,
|
|
75
|
-
minSupportedVersion: "0.0.0",
|
|
76
|
-
},
|
|
77
|
-
crossTabSync: false,
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
const raw = JSON.parse(JSON.stringify(newConfig));
|
|
81
|
-
const merged = mergeFeatureIntoRaw(raw, combinedUpdate);
|
|
82
|
-
writeFileSync(resolvedConfigPath, JSON.stringify(merged, null, 2));
|
|
83
|
-
log.success(`Created swoff.config.json with ${label}`);
|
|
84
|
-
}
|
|
85
|
-
else {
|
|
86
|
-
const raw = JSON.parse(readFileSync(resolvedConfigPath, "utf8"));
|
|
87
|
-
const merged = mergeFeatureIntoRaw(raw, combinedUpdate);
|
|
88
|
-
writeFileSync(resolvedConfigPath, JSON.stringify(merged, null, 2));
|
|
89
|
-
log.success(`Updated swoff.config.json with ${label}`);
|
|
90
51
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
copyEcosystemFiles(projectRoot, eco);
|
|
52
|
+
else if (isJsConfig) {
|
|
53
|
+
log.warn("JS config detected. Converting to swoff.config.json for simplicity.");
|
|
94
54
|
}
|
|
95
|
-
|
|
55
|
+
writeFileSync(resolvedConfigPath, JSON.stringify(mergedConfig, null, 2));
|
|
56
|
+
log.success(`${!configPath ? "Created" : "Updated"} swoff.config.json with ${label}`);
|
|
96
57
|
if (coreFeatures.length > 0) {
|
|
97
58
|
await generateCommand(projectRoot);
|
|
98
59
|
}
|
|
99
60
|
log.success(`${label} added successfully!`);
|
|
100
61
|
}
|
|
101
|
-
function copyEcosystemFiles(projectRoot, name) {
|
|
102
|
-
const src = join(templatesDir, name);
|
|
103
|
-
if (!existsSync(src)) {
|
|
104
|
-
log.warn(`No template files found for "${name}"`);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const swoffDir = join(projectRoot, "swoff", name);
|
|
108
|
-
if (!existsSync(swoffDir)) {
|
|
109
|
-
mkdirSync(swoffDir, { recursive: true });
|
|
110
|
-
}
|
|
111
|
-
let count = 0;
|
|
112
|
-
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
113
|
-
if (entry.isFile()) {
|
|
114
|
-
copyFileSync(join(src, entry.name), join(swoffDir, entry.name));
|
|
115
|
-
count++;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
log.success(`Copied ${count} ${name} file(s) to swoff/${name}/`);
|
|
119
|
-
}
|
|
120
62
|
//# sourceMappingURL=add.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/lib/commands/add.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/lib/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { join } from "path";
|
|
2
2
|
import { log } from "../cli/logger.js";
|
|
3
3
|
import { loadConfigAsync } from "../config/loader.js";
|
|
4
|
-
import { generateAssets } from "../generators/asset-generator/generate.js";
|
|
5
|
-
import { printAssetGuide } from "../generators/asset-generator/guide.js";
|
|
6
4
|
export async function generateAssetsCommand(projectRoot, opts = {}) {
|
|
5
|
+
let assetsPkg;
|
|
6
|
+
try {
|
|
7
|
+
assetsPkg = await import("@swoff/assets");
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
log.error("@swoff/assets is required to generate PWA assets.");
|
|
11
|
+
log.help("Install it with: npm install -D @swoff/assets");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
7
14
|
log.header("Generating PWA Assets");
|
|
8
15
|
const { config } = await loadConfigAsync(projectRoot);
|
|
9
16
|
const assets = config.features.pwa.assets;
|
|
@@ -14,7 +21,7 @@ export async function generateAssetsCommand(projectRoot, opts = {}) {
|
|
|
14
21
|
process.exit(1);
|
|
15
22
|
}
|
|
16
23
|
const outputDir = opts.outputDir || assets.outputDir;
|
|
17
|
-
const result = await generateAssets({
|
|
24
|
+
const result = await assetsPkg.generateAssets({
|
|
18
25
|
source: sourceArg,
|
|
19
26
|
outputDir: join(projectRoot, outputDir),
|
|
20
27
|
appName: config.framework || "App",
|
|
@@ -27,7 +34,7 @@ export async function generateAssetsCommand(projectRoot, opts = {}) {
|
|
|
27
34
|
for (const w of result.warnings)
|
|
28
35
|
log.warn(w);
|
|
29
36
|
}
|
|
30
|
-
printAssetGuide({
|
|
37
|
+
assetsPkg.printAssetGuide({
|
|
31
38
|
appName: config.framework || "App",
|
|
32
39
|
themeColor: assets.themeColor,
|
|
33
40
|
bgColor: assets.bgColor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/lib/commands/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"assets.js","sourceRoot":"","sources":["../../../src/lib/commands/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQtD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,WAAmB,EAAE,OAAsB,EAAE;IACvF,IAAI,SAAyC,CAAC;IAC9C,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QAC/D,GAAG,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,GAAG,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;IAEpC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC;IAE1C,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEzF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,8FAA8F,CAAC,CAAC;QAC1G,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC;QAC5C,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;QACvC,OAAO,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,CAAC,IAAI,CAAC,QAAQ;KAC5B,CAAC,CAAC;IAEH,GAAG,CAAC,OAAO,CAAC,aAAa,MAAM,CAAC,KAAK,CAAC,MAAM,aAAa,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS,CAAC,eAAe,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS;QACT,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ;KAC1B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -20,14 +20,8 @@ export async function cleanCommand(projectRoot, options = {}) {
|
|
|
20
20
|
log.info("No Swoff files found to remove.");
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
log.header("Removing Swoff");
|
|
24
|
-
const targets = [];
|
|
25
|
-
if (hasSwoffDir)
|
|
26
|
-
targets.push("swoff/");
|
|
27
|
-
if (existingConfig)
|
|
28
|
-
targets.push(existingConfig);
|
|
29
23
|
if (!options.yes) {
|
|
30
|
-
const answer = await ask(
|
|
24
|
+
const answer = await ask("Remove Swoff files? [y/N]");
|
|
31
25
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
32
26
|
log.info("Aborted.");
|
|
33
27
|
return;
|
|
@@ -35,12 +29,10 @@ export async function cleanCommand(projectRoot, options = {}) {
|
|
|
35
29
|
}
|
|
36
30
|
if (hasSwoffDir) {
|
|
37
31
|
rmSync(swoffDir, { recursive: true, force: true });
|
|
38
|
-
log.info("Removed swoff/");
|
|
39
32
|
}
|
|
40
33
|
if (existingConfig) {
|
|
41
34
|
rmSync(join(projectRoot, existingConfig));
|
|
42
|
-
log.info(`Removed ${existingConfig}`);
|
|
43
35
|
}
|
|
44
|
-
log.success("
|
|
36
|
+
log.success("Cleaned");
|
|
45
37
|
}
|
|
46
38
|
//# sourceMappingURL=clean.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../../src/lib/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,SAAS,GAAG,CAAC,QAAgB;IAC3B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;YACvC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CACjC,CAAC;IAEF,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,WAAW,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../../src/lib/commands/clean.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAEvC,SAAS,GAAG,CAAC,QAAgB;IAC3B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE;YACvC,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,WAAmB,EACnB,UAAwB,EAAE;IAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,CAAC,mBAAmB,EAAE,iBAAiB,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5C,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CACjC,CAAC;IAEF,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,WAAW,IAAI,CAAC,cAAc,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC;YACnE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5C,CAAC;IAED,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -2,7 +2,7 @@ export function generateGuide(ctx) {
|
|
|
2
2
|
const lines = [];
|
|
3
3
|
const { config, frameworkName, lang } = ctx;
|
|
4
4
|
const ext = lang === "ts" ? "ts" : "js";
|
|
5
|
-
const isReact =
|
|
5
|
+
const isReact = ["react-spa", "nextjs", "remix", "tanstack-start-react", "astro"].includes(frameworkName);
|
|
6
6
|
const hasClientInjector = true;
|
|
7
7
|
lines.push("");
|
|
8
8
|
lines.push(" ── Getting Started ──");
|
|
@@ -18,7 +18,7 @@ export function generateGuide(ctx) {
|
|
|
18
18
|
if (isReact) {
|
|
19
19
|
lines.push("");
|
|
20
20
|
lines.push(" React hook for reactive network state:");
|
|
21
|
-
lines.push(` import { useNetworkStatus } from "../swoff/
|
|
21
|
+
lines.push(` import { useNetworkStatus } from "../swoff/adapters/useNetworkStatus.${ext}x";`);
|
|
22
22
|
lines.push(" const online = useNetworkStatus();");
|
|
23
23
|
}
|
|
24
24
|
lines.push("");
|
|
@@ -27,16 +27,15 @@ export function generateGuide(ctx) {
|
|
|
27
27
|
if (config.features.pwa.enabled) {
|
|
28
28
|
lines.push("");
|
|
29
29
|
lines.push(" ── PWA ──");
|
|
30
|
-
lines.push(` Import in app entry:`);
|
|
31
|
-
lines.push(` import {
|
|
32
|
-
lines.push(" setupPwaInstall();");
|
|
30
|
+
lines.push(` Import in app entry (install prompt is wired automatically by client-injector):`);
|
|
31
|
+
lines.push(` import { isInstallable, promptInstall } from "./swoff/pwa/prompt.${ext}";`);
|
|
33
32
|
lines.push("");
|
|
34
33
|
lines.push(` Link manifest in index.html <head>:`);
|
|
35
34
|
lines.push(` <link rel="manifest" href="/manifest.json">`);
|
|
36
35
|
if (isReact) {
|
|
37
36
|
lines.push("");
|
|
38
|
-
lines.push(" React hooks generated in swoff/
|
|
39
|
-
lines.push(` import { useSWUpdate, useSWProgress } from "../swoff/
|
|
37
|
+
lines.push(" React hooks generated in swoff/adapters/useSWUpdate.tsx:");
|
|
38
|
+
lines.push(` import { useSWUpdate, useSWProgress } from "../swoff/adapters/useSWUpdate.${ext}x";`);
|
|
40
39
|
lines.push("");
|
|
41
40
|
lines.push(" function App() {");
|
|
42
41
|
lines.push(" const { updateStatus, progress, acceptUpdate, dismissUpdate } = useSWUpdate();");
|
|
@@ -51,11 +50,11 @@ export function generateGuide(ctx) {
|
|
|
51
50
|
lines.push("");
|
|
52
51
|
lines.push(" ── Mutation Queue ──");
|
|
53
52
|
lines.push(` Import in mutation handlers:`);
|
|
54
|
-
lines.push(` import { queueMutation, processMutationQueue, getPendingCount } from "./swoff/
|
|
53
|
+
lines.push(` import { queueMutation, processMutationQueue, getPendingCount } from "./swoff/mutation/queue.${ext}";`);
|
|
55
54
|
if (isReact) {
|
|
56
55
|
lines.push("");
|
|
57
|
-
lines.push(" React hook generated in swoff/
|
|
58
|
-
lines.push(` import { useMutationQueue } from "../swoff/
|
|
56
|
+
lines.push(" React hook generated in swoff/adapters/useMutationQueue.tsx:");
|
|
57
|
+
lines.push(` import { useMutationQueue } from "../swoff/adapters/useMutationQueue.${ext}x";`);
|
|
59
58
|
lines.push("");
|
|
60
59
|
lines.push(" function SyncStatus() {");
|
|
61
60
|
lines.push(" const { pending, lastSync } = useMutationQueue();");
|
|
@@ -79,12 +78,12 @@ export function generateGuide(ctx) {
|
|
|
79
78
|
if (config.features.auth.type === "bearer") {
|
|
80
79
|
lines.push("");
|
|
81
80
|
lines.push(" ⚠️ Bearer token is memory-only, it is never persisted to IndexedDB.");
|
|
82
|
-
lines.push(" Page refresh requires re-login.
|
|
81
|
+
lines.push(" Page refresh requires re-login. Extend sessions via adapter.refresh().");
|
|
83
82
|
}
|
|
84
83
|
if (isReact) {
|
|
85
84
|
lines.push("");
|
|
86
|
-
lines.push(" React hook generated in swoff/
|
|
87
|
-
lines.push(` import { useAuth } from "../swoff/
|
|
85
|
+
lines.push(" React hook generated in swoff/adapters/useAuth.tsx:");
|
|
86
|
+
lines.push(` import { useAuth } from "../swoff/adapters/useAuth.${ext}x";`);
|
|
88
87
|
lines.push("");
|
|
89
88
|
lines.push(" function Profile() {");
|
|
90
89
|
lines.push(" const { authenticated, user, online } = useAuth();");
|
|
@@ -93,14 +92,11 @@ export function generateGuide(ctx) {
|
|
|
93
92
|
lines.push(" }");
|
|
94
93
|
if (config.features.mutationQueue.enabled) {
|
|
95
94
|
lines.push("");
|
|
96
|
-
lines.push("
|
|
97
|
-
lines.push(` import { flushMutations } from "../swoff/offline/queue.${ext}";`);
|
|
98
|
-
lines.push(" await setAuth({ token });");
|
|
99
|
-
lines.push(" await flushMutations();");
|
|
95
|
+
lines.push(" ℹ️ clearAuth() also clears the mutation queue automatically — no manual clearQueue needed on logout.");
|
|
100
96
|
}
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
|
-
if (config.features.backgroundSync) {
|
|
99
|
+
if (config.features.mutationQueue.backgroundSync) {
|
|
104
100
|
lines.push("");
|
|
105
101
|
lines.push(" ── Background Sync ──");
|
|
106
102
|
lines.push(" ⚠️ Chrome/Edge only (not supported in Firefox or Safari).");
|
|
@@ -110,8 +106,8 @@ export function generateGuide(ctx) {
|
|
|
110
106
|
}
|
|
111
107
|
if (isReact) {
|
|
112
108
|
lines.push("");
|
|
113
|
-
lines.push(" React hook generated in swoff/
|
|
114
|
-
lines.push(` import { useBackgroundSync } from "../swoff/
|
|
109
|
+
lines.push(" React hook generated in swoff/adapters/useBackgroundSync.tsx:");
|
|
110
|
+
lines.push(` import { useBackgroundSync } from "../swoff/adapters/useBackgroundSync.${ext}x";`);
|
|
115
111
|
lines.push("");
|
|
116
112
|
lines.push(" function SyncPanel() {");
|
|
117
113
|
lines.push(" const { supported, triggerSync } = useBackgroundSync();");
|
|
@@ -130,16 +126,6 @@ export function generateGuide(ctx) {
|
|
|
130
126
|
lines.push("");
|
|
131
127
|
lines.push(` // Invalidate after mutations`);
|
|
132
128
|
lines.push(' await invalidateUrl("/api/todos/42");');
|
|
133
|
-
if (isReact) {
|
|
134
|
-
lines.push("");
|
|
135
|
-
lines.push(" React hook generated in swoff/hooks/useCacheInvalidation.tsx:");
|
|
136
|
-
lines.push(` import { useCacheInvalidation } from "../swoff/hooks/useCacheInvalidation.${ext}x";`);
|
|
137
|
-
lines.push("");
|
|
138
|
-
lines.push(" function InvalidateButton() {");
|
|
139
|
-
lines.push(' const { invalidateUrl } = useCacheInvalidation();');
|
|
140
|
-
lines.push(' return <button onClick={() => invalidateUrl("/api/todos")}>Refresh</button>;');
|
|
141
|
-
lines.push(" }");
|
|
142
|
-
}
|
|
143
129
|
return lines;
|
|
144
130
|
}
|
|
145
131
|
//# sourceMappingURL=generate-guide.js.map
|