@swoff/cli 0.3.13 → 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 +28 -32
- package/dist/index.js +2 -13
- package/dist/index.js.map +1 -1
- package/dist/lib/cli/help.js +3 -8
- package/dist/lib/cli/help.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/generate-guide.js +16 -30
- package/dist/lib/commands/generate-guide.js.map +1 -1
- package/dist/lib/commands/generate.js +31 -6
- package/dist/lib/commands/generate.js.map +1 -1
- package/dist/lib/commands/init.js +188 -11
- 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 +202 -96
- 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 -20
- 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 +51 -1
- 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 +0 -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 +23 -34
- 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 -94
- 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 +183 -59
- package/dist/lib/generators/swoff-files-generator.js.map +1 -1
- package/dist/lib/shared/config-types.js +67 -63
- 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 -1
- 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,7 +52,6 @@ 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 |
|
|
@@ -54,30 +63,17 @@ For PWA asset generation (icons, splash screens, favicons, manifest.json), use t
|
|
|
54
63
|
npx @swoff/assets --source ./logo.svg
|
|
55
64
|
```
|
|
56
65
|
|
|
57
|
-
##
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Read the [CLI reference](./docs/CLI.md) for detailed information on each command.
|
|
69
|
-
|
|
70
|
-
## Architecture
|
|
71
|
-
|
|
72
|
-
Read the [architecture](./docs/ARCHITECTURE.md) for detailed information on the project's architecture.
|
|
73
|
-
|
|
74
|
-
## Comparison With Other Popular Tools
|
|
75
|
-
|
|
76
|
-
Read the [comparison](./docs/COMPARISON.md) for a comprehensive comparison with popular tools.
|
|
77
|
-
|
|
78
|
-
## Ecosystem
|
|
79
|
-
|
|
80
|
-
Read the [ecosystem](./docs/ECOSYSTEM.md) to see how swoff integrates with any web framework you can work with.
|
|
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 |
|
|
81
77
|
|
|
82
78
|
---
|
|
83
79
|
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,6 @@ 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
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
12
|
const packageDir = join(__dirname, "..");
|
|
@@ -28,6 +27,7 @@ const { values, positionals } = parseArgs({
|
|
|
28
27
|
help: { type: "boolean", short: "h" },
|
|
29
28
|
framework: { type: "string" },
|
|
30
29
|
language: { type: "string" },
|
|
30
|
+
debug: { type: "boolean" },
|
|
31
31
|
yes: { type: "boolean", short: "y" },
|
|
32
32
|
},
|
|
33
33
|
allowPositionals: true,
|
|
@@ -48,23 +48,12 @@ async function main() {
|
|
|
48
48
|
break;
|
|
49
49
|
}
|
|
50
50
|
case "generate": {
|
|
51
|
-
await generateCommand(projectRoot, { language: values.language });
|
|
51
|
+
await generateCommand(projectRoot, { language: values.language, debug: !!values.debug });
|
|
52
52
|
break;
|
|
53
53
|
}
|
|
54
54
|
case "validate":
|
|
55
55
|
await validateCommand(projectRoot);
|
|
56
56
|
break;
|
|
57
|
-
case "add": {
|
|
58
|
-
const feature = positionals.slice(1).join(",");
|
|
59
|
-
if (!feature) {
|
|
60
|
-
log.error("Please specify a feature to add");
|
|
61
|
-
log.info("Usage: swoff add <feature1>[,<feature2>,...]");
|
|
62
|
-
log.info("Features: mutation-queue, pwa, cross-tab, auth, tag-invalidation, background-sync, graphql, push-notification, htmx, php");
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
await addCommand(projectRoot, feature);
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
57
|
case "clean":
|
|
69
58
|
await cleanCommand(projectRoot, { yes: !!values.yes });
|
|
70
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,8 +6,8 @@ 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
13
|
description: "Generate supporting files (swoff/)",
|
|
@@ -19,13 +19,8 @@ export const commands = {
|
|
|
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
22
|
clean: {
|
|
28
|
-
description: "Remove Swoff from the project (swoff/, config
|
|
23
|
+
description: "Remove Swoff from the project (swoff/, config). Use --yes to skip confirmation",
|
|
29
24
|
usage: "swoff clean [--yes|-y]",
|
|
30
25
|
examples: ["swoff clean", "swoff clean --yes"],
|
|
31
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/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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"}
|
|
@@ -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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-guide.js","sourceRoot":"","sources":["../../../src/lib/commands/generate-guide.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,aAAa,CAAC,GAAiB;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;IAC5C,MAAM,GAAG,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAExC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"generate-guide.js","sourceRoot":"","sources":["../../../src/lib/commands/generate-guide.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { loadConfigAsync } from "../config/loader.js";
|
|
2
|
+
import { validateConfig } from "../config/validator.js";
|
|
2
3
|
import { detectProjectLanguage } from "../utils/detect-language.js";
|
|
3
4
|
import { generateFiles } from "../generators/swoff-files-generator.js";
|
|
5
|
+
import { hasBundler } from "../generators/file-generators/context.js";
|
|
4
6
|
import { join } from "path";
|
|
5
7
|
import { log } from "../cli/logger.js";
|
|
6
8
|
export async function generateCommand(projectRoot, options = {}) {
|
|
7
|
-
const { language } = options;
|
|
9
|
+
const { language, debug } = options;
|
|
8
10
|
const { config, configPath } = await loadConfigAsync(projectRoot);
|
|
9
11
|
if (!configPath) {
|
|
10
12
|
log.warn('No swoff.config.json found. Run "swoff init" first.');
|
|
11
13
|
return;
|
|
12
14
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
const cfgErrors = validateConfig(config);
|
|
16
|
+
if (cfgErrors.length > 0) {
|
|
17
|
+
log.error("Configuration validation failed:");
|
|
18
|
+
for (const err of cfgErrors) {
|
|
19
|
+
log.error(` - ${err}`);
|
|
20
|
+
}
|
|
15
21
|
return;
|
|
16
22
|
}
|
|
17
23
|
log.dim(`Config: ${configPath}`);
|
|
@@ -21,13 +27,16 @@ export async function generateCommand(projectRoot, options = {}) {
|
|
|
21
27
|
const ext = detectedLang === "ts" ? "ts" : "js";
|
|
22
28
|
const swoffDir = join(projectRoot, "swoff");
|
|
23
29
|
const generatedFiles = [];
|
|
30
|
+
const fwName = config.framework ?? "vanilla";
|
|
24
31
|
const ctx = {
|
|
25
32
|
config,
|
|
26
33
|
projectRoot,
|
|
27
34
|
swoffDir,
|
|
28
35
|
ext,
|
|
29
36
|
generatedFiles,
|
|
30
|
-
frameworkName:
|
|
37
|
+
frameworkName: fwName,
|
|
38
|
+
hasBundler: hasBundler(fwName),
|
|
39
|
+
debug: debug ?? false,
|
|
31
40
|
};
|
|
32
41
|
try {
|
|
33
42
|
const files = generateFiles(ctx);
|
|
@@ -38,13 +47,29 @@ export async function generateCommand(projectRoot, options = {}) {
|
|
|
38
47
|
return;
|
|
39
48
|
}
|
|
40
49
|
log.success("Generation complete!");
|
|
50
|
+
if (!config.build.precacheDirs || Object.keys(config.build.precacheDirs).length === 0) {
|
|
51
|
+
log.normal("");
|
|
52
|
+
log.warn("No directories configured for precaching. Only explicit fallback routes will be precached.");
|
|
53
|
+
log.help(" Add precacheDirs to your swoff.config.json build section to precache assets:");
|
|
54
|
+
log.help(` "precacheDirs": { "${config.build.outputDir}": { "prefix": "/" } }`);
|
|
55
|
+
}
|
|
41
56
|
if (config.features.pwa.enabled) {
|
|
42
57
|
log.normal("");
|
|
43
58
|
log.help(`For PWA assets: run 'npx @swoff/assets --source <path>' to generate icons, splash screens, and manifest.json`);
|
|
44
59
|
}
|
|
60
|
+
if (config.features.auth.enabled && hasBundler(fwName)) {
|
|
61
|
+
log.normal("");
|
|
62
|
+
log.help(`Auth (${config.features.auth.type})`);
|
|
63
|
+
log.normal(" Edit swoff/auth/adapter.ts to match your backend:");
|
|
64
|
+
log.normal(" - getHeaders(): return auth headers for fetch requests");
|
|
65
|
+
if (config.features.auth.type !== "cookie") {
|
|
66
|
+
log.normal(" - refresh(): implement token/session refresh");
|
|
67
|
+
}
|
|
68
|
+
log.normal(" - fetchUser(): implement fetching current user (/api/me)");
|
|
69
|
+
log.normal(" Use { auth: true } in fetchWithCache for authenticated requests");
|
|
70
|
+
}
|
|
45
71
|
log.normal("");
|
|
46
|
-
log.normal("1.
|
|
47
|
-
log.normal("2. After each build, run the SW generator:");
|
|
72
|
+
log.normal("1. After each build, run the SW generator:");
|
|
48
73
|
log.normal(" node swoff/sw/generator.js (Add this to your build script if you want it automated)");
|
|
49
74
|
}
|
|
50
75
|
//# sourceMappingURL=generate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/lib/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAEvE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/lib/commands/generate.ts"],"names":[],"mappings":"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"}
|