@mayson-org/inject-script 1.0.8 → 1.0.9

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.
Files changed (45) hide show
  1. package/.env.example +4 -1
  2. package/README.md +33 -7
  3. package/assets/pwa/mayson-logo-dark-192x192.png +0 -0
  4. package/assets/pwa/mayson-logo-dark-512x512-maskable.png +0 -0
  5. package/assets/pwa/mayson-logo-dark-512x512.png +0 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +18 -3
  8. package/dist/core/generators.d.ts.map +1 -1
  9. package/dist/core/generators.js +5 -4
  10. package/dist/core/types.d.ts +26 -6
  11. package/dist/core/types.d.ts.map +1 -1
  12. package/dist/index.d.ts +10 -3
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +84 -20
  15. package/dist/plugins/index.d.ts +2 -1
  16. package/dist/plugins/index.d.ts.map +1 -1
  17. package/dist/plugins/index.js +3 -1
  18. package/dist/plugins/pwa/index.d.ts +9 -0
  19. package/dist/plugins/pwa/index.d.ts.map +1 -0
  20. package/dist/plugins/pwa/index.js +11 -0
  21. package/dist/plugins/pwa/inject-project.d.ts +4 -0
  22. package/dist/plugins/pwa/inject-project.d.ts.map +1 -0
  23. package/dist/plugins/pwa/inject-project.js +169 -0
  24. package/dist/plugins/pwa/patch-layout-metadata.d.ts +14 -0
  25. package/dist/plugins/pwa/patch-layout-metadata.d.ts.map +1 -0
  26. package/dist/plugins/pwa/patch-layout-metadata.js +162 -0
  27. package/dist/plugins/pwa/templates/install-prompt.d.ts +3 -0
  28. package/dist/plugins/pwa/templates/install-prompt.d.ts.map +1 -0
  29. package/dist/plugins/pwa/templates/install-prompt.js +186 -0
  30. package/dist/plugins/pwa/templates/manifest.d.ts +11 -0
  31. package/dist/plugins/pwa/templates/manifest.d.ts.map +1 -0
  32. package/dist/plugins/pwa/templates/manifest.js +44 -0
  33. package/dist/plugins/pwa/templates/service-worker-register.d.ts +3 -0
  34. package/dist/plugins/pwa/templates/service-worker-register.d.ts.map +1 -0
  35. package/dist/plugins/pwa/templates/service-worker-register.js +23 -0
  36. package/dist/plugins/pwa/templates/sw.js.d.ts +6 -0
  37. package/dist/plugins/pwa/templates/sw.js.d.ts.map +1 -0
  38. package/dist/plugins/pwa/templates/sw.js.js +55 -0
  39. package/dist/shared/config.d.ts +2 -0
  40. package/dist/shared/config.d.ts.map +1 -1
  41. package/dist/shared/config.js +2 -0
  42. package/dist/shared/generated-app-metadata.d.ts +3 -2
  43. package/dist/shared/generated-app-metadata.d.ts.map +1 -1
  44. package/dist/shared/generated-app-metadata.js +3 -0
  45. package/package.json +4 -2
package/.env.example CHANGED
@@ -5,5 +5,8 @@ MAYSON_COLLECTION_ID=
5
5
  MAYSON_API_BASE_URL=
6
6
  MAYSON_APP_BASE_URL=https://mayson.dev
7
7
 
8
- # Auth for generated-app-metadata (show_remix_pill / enable_remix)
8
+ # Auth for generated-app-metadata (show_remix_pill / enable_remix / website_title)
9
9
  MAYSON_WEB_TOKEN=
10
+
11
+ # Optional PWA/manifest name (else API website_title, else "My App")
12
+ # MAYSON_WEBSITE_TITLE=
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @mayson-org/inject-script
2
2
 
3
- Locate the Next.js App Router root layout, generate Mayson plugin components next to it, and inject imports + JSX into the layout. Injection logic is unchanged; plugins supply component source.
3
+ Locate the Next.js App Router root layout, generate Mayson plugin components next to it, and inject imports + JSX into the layout. Injection logic is unchanged; plugins supply component source. The **pwa** plugin also writes project-level artifacts (`public/`, `manifest.ts`, layout meta).
4
4
 
5
5
  Requires **Node 20+**.
6
6
 
@@ -15,10 +15,13 @@ npx @mayson-org/inject-script --type=watermark
15
15
  ## Quick usage
16
16
 
17
17
  ```bash
18
+ npx @mayson-org/inject-script # watermark + ascii + pwa
18
19
  npx @mayson-org/inject-script --type=watermark
20
+ npx @mayson-org/inject-script --type=pwa
19
21
  npx @mayson-org/inject-script --type=all
22
+ npx @mayson-org/inject-script --no-pwa
20
23
  npx @mayson-org/inject-script --type=watermark --dry-run
21
- npx @mayson-org/inject-script --dir=./my-app --type=watermark
24
+ npx @mayson-org/inject-script --dir=./my-app
22
25
  ```
23
26
 
24
27
  ## Watermark
@@ -42,6 +45,7 @@ Header: `M-Web-Token: {MAYSON_WEB_TOKEN}`
42
45
  |-----------|--------|
43
46
  | `show_remix_pill` | If `false`, watermark is **not** injected; if `true`, inject |
44
47
  | `enable_remix` | Still fetched for later use; click target is hardcoded to https://mayson.dev/ for now |
48
+ | `website_title` | Optional; used as PWA manifest `name` / `short_name` when present |
45
49
 
46
50
  **Metadata not found (404):** if the API returns HTTP 404 or a body like `{ "response_code": 404, "message": "Generated app metadata not found", "value": {} }`, treat as **`show_remix_pill=true`** and **`enable_remix=true`** (show watermark).
47
51
 
@@ -56,13 +60,33 @@ Defaults when the API is not called or fails for other reasons: `showRemixPill=f
56
60
  | `MAYSON_API_BASE_URL` | API base for metadata |
57
61
  | `MAYSON_APP_BASE_URL` | App base (default `https://mayson.dev`) |
58
62
  | `MAYSON_WEB_TOKEN` | Auth for generated-app-metadata |
63
+ | `MAYSON_WEBSITE_TITLE` | Optional PWA/manifest app name (else API `website_title`, else `"My App"`) |
64
+
65
+ ## PWA
66
+
67
+ Default-on (like ascii). Skip with `--no-pwa`.
68
+
69
+ Writes / patches:
70
+
71
+ | Target | Behavior |
72
+ |--------|----------|
73
+ | `{layoutDir}/MaysonServiceWorkerRegister.tsx` | Prod-only `/sw.js` register; layout-injected |
74
+ | `{layoutDir}/MaysonInstallPrompt.tsx` | Install UI (`beforeinstallprompt`, iOS hint, `?pwa_install=1`); inline styles |
75
+ | `{appDir}/manifest.ts` | Write if missing; refresh if marked `@mayson-pwa-manifest`; else skip |
76
+ | `{projectRoot}/public/sw.js` | Write/overwrite if missing or marked `@mayson-pwa-sw` (`mayson-pwa-v1` cache) |
77
+ | `{projectRoot}/public/icons/*.png` | Copy default Mayson icons if missing (never overwrite) |
78
+ | Root layout metadata | Insert `appleWebApp` / `viewport.themeColor` when absent |
79
+
80
+ No `next-pwa` / Workbox deps. Custom unmarked `manifest.ts` / `sw.js` are left alone.
59
81
 
60
82
  ## Programmatic API
61
83
 
62
84
  ```ts
63
85
  import { runAutoInject } from '@mayson-org/inject-script';
64
86
 
65
- const result = await runAutoInject(process.cwd()); // watermark + ascii by default
87
+ const result = await runAutoInject(process.cwd()); // watermark + ascii + pwa
88
+ await runAutoInject(process.cwd(), { types: ['pwa'], dryRun: true });
89
+ await runAutoInject(process.cwd(), { pwa: false }); // skip PWA
66
90
  ```
67
91
 
68
92
  ## Package layout
@@ -72,13 +96,15 @@ src/
72
96
  cli.ts / index.ts
73
97
  core/ # find-root-layout, injector, generators
74
98
  plugins/watermark/ # remix pill template
75
- plugins/ascii|metadata # stubs for later restores
99
+ plugins/ascii|metadata
100
+ plugins/pwa/ # multi-artifact injectProject
76
101
  shared/ # config, generated-app-metadata, remix-url
102
+ assets/pwa/ # default PWA icons shipped with the package
77
103
  ```
78
104
 
79
105
  ## Notes
80
106
 
81
- - Default inject is **watermark + ascii** (override with `--type`).
82
- - Watermark is still gated by `show_remix_pill`; ascii always injects when selected.
83
- - Idempotent: skips components already present in the layout.
107
+ - Default inject is **watermark + ascii + pwa** (override with `--type` / `--no-pwa`).
108
+ - Watermark is gated by `show_remix_pill`; ascii and pwa always inject when selected.
109
+ - Idempotent: skips components already present; does not clobber custom icons or unmarked PWA files.
84
110
  - Does not patch `.next` HTML; source inject only.
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAwDA,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DtE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAkEA,wBAAsB,IAAI,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DtE"}
package/dist/cli.js CHANGED
@@ -11,7 +11,9 @@ Usage:
11
11
 
12
12
  Options:
13
13
  --dir <path> Target project root (default: cwd)
14
- --type <type> watermark | ascii | metadata | all (default: watermark + ascii)
14
+ --type <type> watermark | ascii | metadata | pwa | all
15
+ (default: watermark + ascii + pwa)
16
+ --no-pwa Skip PWA artifacts even when included by default / --type=all
15
17
  --dry-run Preview without writing files
16
18
  --help, -h Show help
17
19
 
@@ -19,13 +21,19 @@ Watermark gating (inject-time):
19
21
  Fetches generated-app-metadata when MAYSON_WORKSPACE_ID, MAYSON_COLLECTION_ID,
20
22
  MAYSON_API_BASE_URL, and MAYSON_WEB_TOKEN are set. Injects watermark only when
21
23
  show_remix_pill is true; bakes enable_remix into the generated component.
24
+
25
+ PWA (default on):
26
+ Writes MaysonServiceWorkerRegister + MaysonInstallPrompt beside the layout,
27
+ app/manifest.ts, public/sw.js, default icons under public/icons/, and patches
28
+ appleWebApp / viewport.themeColor when missing.
22
29
  `);
23
30
  }
24
31
  function parseArgs(argv) {
25
32
  const options = {
26
33
  projectRoot: process.cwd(),
27
- types: ['watermark', 'ascii'],
34
+ types: ['watermark', 'ascii', 'pwa'],
28
35
  dryRun: false,
36
+ pwa: true,
29
37
  help: false,
30
38
  };
31
39
  for (let i = 0; i < argv.length; i++) {
@@ -36,6 +44,9 @@ function parseArgs(argv) {
36
44
  else if (arg === '--dry-run') {
37
45
  options.dryRun = true;
38
46
  }
47
+ else if (arg === '--no-pwa') {
48
+ options.pwa = false;
49
+ }
39
50
  else if (arg.startsWith('--type=')) {
40
51
  options.types = [arg.split('=')[1]];
41
52
  }
@@ -62,7 +73,11 @@ export async function main(argv = process.argv.slice(2)) {
62
73
  return;
63
74
  }
64
75
  console.log(`Searching for Next.js root layout in: ${options.projectRoot}`);
65
- const result = await runAutoInject(options.projectRoot, options.types, options.dryRun);
76
+ const result = await runAutoInject(options.projectRoot, {
77
+ types: options.types,
78
+ dryRun: options.dryRun,
79
+ pwa: options.pwa,
80
+ });
66
81
  if (!result.success) {
67
82
  console.error(`Error: ${result.error}`);
68
83
  process.exitCode = 1;
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/core/generators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,yBAAyB,EACzB,aAAa,EACb,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAQpB,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EAAE,YAAyB,EAC/C,OAAO,EAAE,yBAAyB,GACjC,sBAAsB,EAAE,CAkC1B"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/core/generators.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,yBAAyB,EACzB,aAAa,EACb,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,yBAAyB,EACzB,aAAa,EACb,sBAAsB,GACvB,MAAM,YAAY,CAAC;AASpB,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,aAAa,EAAE,YAAyB,EAC/C,OAAO,EAAE,yBAAyB,GACjC,sBAAsB,EAAE,CAoC1B"}
@@ -1,7 +1,8 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { plugins } from '../plugins/index.js';
4
- const ALL_TYPES = [
4
+ /** Layout-component plugin types (have generateSource). */
5
+ const LAYOUT_COMPONENT_TYPES = [
5
6
  'watermark',
6
7
  'ascii',
7
8
  'metadata',
@@ -14,11 +15,11 @@ export function generateComponents(types = ['watermark', 'ascii'], options) {
14
15
  fs.mkdirSync(outputDir, { recursive: true });
15
16
  }
16
17
  const selectedTypes = types.includes('all')
17
- ? ALL_TYPES
18
- : types.filter((t) => t !== 'all');
18
+ ? LAYOUT_COMPONENT_TYPES
19
+ : types.filter((t) => t !== 'all' && t !== 'pwa');
19
20
  for (const type of selectedTypes) {
20
21
  const plugin = plugins[type];
21
- if (!plugin) {
22
+ if (!plugin?.generateSource || !plugin.name) {
22
23
  continue;
23
24
  }
24
25
  const code = plugin.generateSource(options.context);
@@ -1,11 +1,11 @@
1
- export type ComponentType = 'watermark' | 'ascii' | 'metadata' | 'all';
1
+ export type ComponentType = 'watermark' | 'ascii' | 'metadata' | 'pwa' | 'all';
2
2
  export interface GeneratedComponentInfo {
3
3
  name: string;
4
4
  filePath: string;
5
5
  importStatement: string;
6
6
  jsxTag: string;
7
7
  }
8
- /** Context passed into plugin generateSource (e.g. watermark flags from API). */
8
+ /** Context passed into plugin generateSource / injectProject. */
9
9
  export type PluginGenerateContext = {
10
10
  watermark?: {
11
11
  showRemixPill: boolean;
@@ -13,6 +13,12 @@ export type PluginGenerateContext = {
13
13
  appBaseUrl: string;
14
14
  collectionId: string;
15
15
  };
16
+ pwa?: {
17
+ appName: string;
18
+ themeColor: string;
19
+ backgroundColor: string;
20
+ description: string;
21
+ };
16
22
  };
17
23
  export interface ComponentGeneratorOptions {
18
24
  outputDir: string;
@@ -37,12 +43,26 @@ export interface InjectorResult {
37
43
  /** Extra notes (e.g. watermark skipped because show_remix_pill is false). */
38
44
  messages?: string[];
39
45
  }
46
+ export type ProjectInjectContext = {
47
+ projectRoot: string;
48
+ layoutPath: string;
49
+ dryRun?: boolean;
50
+ isTypeScript?: boolean;
51
+ context?: PluginGenerateContext;
52
+ };
53
+ export type ProjectInjectResult = {
54
+ messages: string[];
55
+ injectedComponents: string[];
56
+ skippedComponents: string[];
57
+ };
40
58
  /** Descriptor for a generate-and-inject plugin. */
41
59
  export interface MaysonPlugin {
42
60
  type: Exclude<ComponentType, 'all'>;
43
- /** Exported React component name, e.g. MaysonWatermark */
44
- name: string;
45
- /** Source for the component file written next to the root layout */
46
- generateSource: (context?: PluginGenerateContext) => string;
61
+ /** Exported React component name (layout-component plugins). */
62
+ name?: string;
63
+ /** Source for a component file written next to the root layout. */
64
+ generateSource?: (context?: PluginGenerateContext) => string;
65
+ /** Multi-file project inject (e.g. PWA public/ + manifest). */
66
+ injectProject?: (ctx: ProjectInjectContext) => ProjectInjectResult;
47
67
  }
48
68
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,KAAK,CAAC;AAEvE,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,iFAAiF;AACjF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE;QACV,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACpC,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,MAAM,CAAC;CAC7D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,OAAO,GACP,UAAU,GACV,KAAK,GACL,KAAK,CAAC;AAEV,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,iEAAiE;AACjE,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE;QACV,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,GAAG,CAAC,EAAE;QACJ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,qBAAqB,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AAEF,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACpC,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,qBAAqB,KAAK,MAAM,CAAC;IAC7D,+DAA+D;IAC/D,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,mBAAmB,CAAC;CACpE"}
package/dist/index.d.ts CHANGED
@@ -10,11 +10,18 @@ export type { MaysonEnvConfig } from './shared/config.js';
10
10
  export { fetchGeneratedAppMetadata, resolveMaysonConfig, shouldFetchGeneratedAppMetadata, } from './shared/generated-app-metadata.js';
11
11
  export { watermarkPlugin, buildMaysonWatermarkSource, } from './plugins/watermark/index.js';
12
12
  export { asciiPlugin, buildMaysonAsciiSource, } from './plugins/ascii/index.js';
13
+ export { pwaPlugin, injectPwaProject, buildMaysonServiceWorkerRegisterSource, buildMaysonInstallPromptSource, buildManifestSource, buildSwJsSource, patchLayoutPwaMetadata, } from './plugins/pwa/index.js';
13
14
  export { BUILD_WITH_LOVE_ASCII, MAYSON_LETTER_ASCII, } from './shared/ascii-art.js';
14
- export type { ComponentType, GeneratedComponentInfo, ComponentGeneratorOptions, InjectorOptions, InjectorResult, MaysonPlugin, PluginGenerateContext, } from './core/types.js';
15
+ export type { ComponentType, GeneratedComponentInfo, ComponentGeneratorOptions, InjectorOptions, InjectorResult, MaysonPlugin, PluginGenerateContext, ProjectInjectContext, ProjectInjectResult, } from './core/types.js';
16
+ export type RunAutoInjectOptions = {
17
+ types?: ComponentType[];
18
+ dryRun?: boolean;
19
+ /** When false, skip PWA even if listed in types (CLI `--no-pwa`). Default true. */
20
+ pwa?: boolean;
21
+ };
15
22
  /**
16
23
  * Auto-detect root layout, fetch watermark flags from generated-app-metadata when
17
- * configured, generate component files, and inject them.
24
+ * configured, generate component files / project artifacts, and inject them.
18
25
  */
19
- export declare function runAutoInject(projectRoot?: string, types?: ComponentType[], dryRun?: boolean): Promise<InjectorResult>;
26
+ export declare function runAutoInject(projectRoot?: string, typesOrOptions?: ComponentType[] | RunAutoInjectOptions, dryRunArg?: boolean): Promise<InjectorResult>;
20
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,WAAW,EACX,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAiDzB;;;GAGG;AACH,wBAAsB,aAAa,CACjC,WAAW,GAAE,MAAsB,EACnC,KAAK,GAAE,aAAa,EAA2B,EAC/C,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,cAAc,CAAC,CAkEzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EAEf,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,WAAW,EACX,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,sCAAsC,EACtC,8BAA8B,EAC9B,mBAAmB,EACnB,eAAe,EACf,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,cAAc,EACd,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAKzB,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AA4EF;;;GAGG;AACH,wBAAsB,aAAa,CACjC,WAAW,GAAE,MAAsB,EACnC,cAAc,GAAE,aAAa,EAAE,GAAG,oBAAoC,EACtE,SAAS,GAAE,OAAe,GACzB,OAAO,CAAC,cAAc,CAAC,CA+GzB"}
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { findRootLayout } from './core/find-root-layout.js';
3
3
  import { generateComponents } from './core/generators.js';
4
4
  import { injectComponentsIntoLayout } from './core/injector.js';
5
5
  import { deleteGeneratedComponentFile, removeComponentFromLayout, } from './core/remove-component.js';
6
+ import { plugins } from './plugins/index.js';
6
7
  import { resolveMaysonConfig } from './shared/generated-app-metadata.js';
7
8
  export { findRootLayout } from './core/find-root-layout.js';
8
9
  export { generateComponents } from './core/generators.js';
@@ -13,12 +14,35 @@ export { loadMaysonEnvConfig } from './shared/config.js';
13
14
  export { fetchGeneratedAppMetadata, resolveMaysonConfig, shouldFetchGeneratedAppMetadata, } from './shared/generated-app-metadata.js';
14
15
  export { watermarkPlugin, buildMaysonWatermarkSource, } from './plugins/watermark/index.js';
15
16
  export { asciiPlugin, buildMaysonAsciiSource, } from './plugins/ascii/index.js';
17
+ export { pwaPlugin, injectPwaProject, buildMaysonServiceWorkerRegisterSource, buildMaysonInstallPromptSource, buildManifestSource, buildSwJsSource, patchLayoutPwaMetadata, } from './plugins/pwa/index.js';
16
18
  export { BUILD_WITH_LOVE_ASCII, MAYSON_LETTER_ASCII, } from './shared/ascii-art.js';
17
- function filterTypesForConfig(types, showRemixPill) {
19
+ const DEFAULT_TYPES = ['watermark', 'ascii', 'pwa'];
20
+ const ALL_TYPES = ['watermark', 'ascii', 'metadata', 'pwa'];
21
+ function normalizeArgs(typesOrOptions, dryRunArg) {
22
+ if (Array.isArray(typesOrOptions)) {
23
+ return {
24
+ types: typesOrOptions.length > 0 ? typesOrOptions : DEFAULT_TYPES,
25
+ dryRun: dryRunArg,
26
+ pwaEnabled: true,
27
+ };
28
+ }
29
+ return {
30
+ types: typesOrOptions.types && typesOrOptions.types.length > 0
31
+ ? typesOrOptions.types
32
+ : DEFAULT_TYPES,
33
+ dryRun: typesOrOptions.dryRun ?? dryRunArg,
34
+ pwaEnabled: typesOrOptions.pwa !== false,
35
+ };
36
+ }
37
+ function filterTypesForConfig(types, showRemixPill, pwaEnabled) {
18
38
  const messages = [];
19
- const selected = types.includes('all')
20
- ? ['watermark', 'ascii', 'metadata']
21
- : types;
39
+ let selected = types.includes('all') ? [...ALL_TYPES] : [...types];
40
+ if (!pwaEnabled) {
41
+ if (selected.includes('pwa')) {
42
+ messages.push('pwa skipped (--no-pwa)');
43
+ }
44
+ selected = selected.filter((t) => t !== 'pwa');
45
+ }
22
46
  if (selected.includes('watermark') && !showRemixPill) {
23
47
  messages.push('watermark disabled — show_remix_pill is false (removing pill if present)');
24
48
  return {
@@ -40,9 +64,10 @@ function stripWatermark(layoutPath, dryRun, messages) {
40
64
  }
41
65
  /**
42
66
  * Auto-detect root layout, fetch watermark flags from generated-app-metadata when
43
- * configured, generate component files, and inject them.
67
+ * configured, generate component files / project artifacts, and inject them.
44
68
  */
45
- export async function runAutoInject(projectRoot = process.cwd(), types = ['watermark', 'ascii'], dryRun = false) {
69
+ export async function runAutoInject(projectRoot = process.cwd(), typesOrOptions = DEFAULT_TYPES, dryRunArg = false) {
70
+ const { types, dryRun, pwaEnabled } = normalizeArgs(typesOrOptions, dryRunArg);
46
71
  const layoutPath = findRootLayout(projectRoot);
47
72
  if (!layoutPath) {
48
73
  return {
@@ -55,7 +80,7 @@ export async function runAutoInject(projectRoot = process.cwd(), types = ['water
55
80
  }
56
81
  const config = await resolveMaysonConfig();
57
82
  console.log(`[mayson] resolved show_remix_pill=${config.showRemixPill} enable_remix=${config.enableRemix}`);
58
- const { types: effectiveTypes, messages, removeWatermark } = filterTypesForConfig(types, config.showRemixPill);
83
+ const { types: effectiveTypes, messages, removeWatermark } = filterTypesForConfig(types, config.showRemixPill, pwaEnabled);
59
84
  if (removeWatermark) {
60
85
  stripWatermark(layoutPath, dryRun, messages);
61
86
  }
@@ -75,22 +100,61 @@ export async function runAutoInject(projectRoot = process.cwd(), types = ['water
75
100
  appBaseUrl: config.appBaseUrl,
76
101
  collectionId: config.collectionId,
77
102
  },
103
+ pwa: {
104
+ appName: config.websiteTitle.trim() || 'My App',
105
+ themeColor: '#0a0a0a',
106
+ backgroundColor: '#ffffff',
107
+ description: 'Generated by Mayson',
108
+ },
78
109
  };
79
110
  const isTypeScript = layoutPath.endsWith('.tsx') || layoutPath.endsWith('.ts');
80
111
  const targetDir = path.dirname(layoutPath);
81
- const generatedComponents = generateComponents(effectiveTypes, {
82
- outputDir: targetDir,
83
- isTypeScript,
84
- dryRun,
85
- context,
86
- });
87
- const result = injectComponentsIntoLayout({
88
- filePath: layoutPath,
89
- components: generatedComponents,
90
- dryRun,
91
- });
112
+ const layoutTypes = effectiveTypes.filter((t) => t !== 'pwa' && t !== 'all');
113
+ const injectedComponents = [];
114
+ const skippedComponents = [];
115
+ if (layoutTypes.length > 0) {
116
+ const generatedComponents = generateComponents(layoutTypes, {
117
+ outputDir: targetDir,
118
+ isTypeScript,
119
+ dryRun,
120
+ context,
121
+ });
122
+ const result = injectComponentsIntoLayout({
123
+ filePath: layoutPath,
124
+ components: generatedComponents,
125
+ dryRun,
126
+ });
127
+ if (!result.success && result.error) {
128
+ return {
129
+ ...result,
130
+ messages: [...(result.messages ?? []), ...messages],
131
+ };
132
+ }
133
+ injectedComponents.push(...result.injectedComponents);
134
+ skippedComponents.push(...result.skippedComponents);
135
+ }
136
+ for (const type of effectiveTypes) {
137
+ if (type === 'all')
138
+ continue;
139
+ const plugin = plugins[type];
140
+ if (!plugin?.injectProject)
141
+ continue;
142
+ const projectResult = plugin.injectProject({
143
+ projectRoot,
144
+ layoutPath,
145
+ dryRun,
146
+ isTypeScript,
147
+ context,
148
+ });
149
+ messages.push(...projectResult.messages);
150
+ injectedComponents.push(...projectResult.injectedComponents);
151
+ skippedComponents.push(...projectResult.skippedComponents);
152
+ }
92
153
  return {
93
- ...result,
94
- messages: [...(result.messages ?? []), ...messages],
154
+ success: true,
155
+ filePath: layoutPath,
156
+ injectedComponents,
157
+ skippedComponents,
158
+ messages,
95
159
  };
96
160
  }
@@ -1,7 +1,8 @@
1
1
  import type { MaysonPlugin } from '../core/types.js';
2
2
  import { asciiPlugin } from './ascii/index.js';
3
3
  import { metadataPlugin } from './metadata/index.js';
4
+ import { pwaPlugin } from './pwa/index.js';
4
5
  import { watermarkPlugin } from './watermark/index.js';
5
6
  export declare const plugins: Record<Exclude<MaysonPlugin['type'], never>, MaysonPlugin>;
6
- export { watermarkPlugin, asciiPlugin, metadataPlugin };
7
+ export { watermarkPlugin, asciiPlugin, metadataPlugin, pwaPlugin };
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EAAE,YAAY,CAI9E,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,eAAO,MAAM,OAAO,EAAE,MAAM,CAC1B,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EACpC,YAAY,CAMb,CAAC;AAEF,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC"}
@@ -1,9 +1,11 @@
1
1
  import { asciiPlugin } from './ascii/index.js';
2
2
  import { metadataPlugin } from './metadata/index.js';
3
+ import { pwaPlugin } from './pwa/index.js';
3
4
  import { watermarkPlugin } from './watermark/index.js';
4
5
  export const plugins = {
5
6
  watermark: watermarkPlugin,
6
7
  ascii: asciiPlugin,
7
8
  metadata: metadataPlugin,
9
+ pwa: pwaPlugin,
8
10
  };
9
- export { watermarkPlugin, asciiPlugin, metadataPlugin };
11
+ export { watermarkPlugin, asciiPlugin, metadataPlugin, pwaPlugin };
@@ -0,0 +1,9 @@
1
+ import type { MaysonPlugin } from '../../core/types.js';
2
+ export declare const pwaPlugin: MaysonPlugin;
3
+ export { injectPwaProject } from './inject-project.js';
4
+ export { buildMaysonServiceWorkerRegisterSource } from './templates/service-worker-register.js';
5
+ export { buildMaysonInstallPromptSource } from './templates/install-prompt.js';
6
+ export { buildManifestSource } from './templates/manifest.js';
7
+ export { buildSwJsSource } from './templates/sw.js.js';
8
+ export { patchLayoutPwaMetadata } from './patch-layout-metadata.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/pwa/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,eAAO,MAAM,SAAS,EAAE,YAGvB,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sCAAsC,EAAE,MAAM,wCAAwC,CAAC;AAChG,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { injectPwaProject } from './inject-project.js';
2
+ export const pwaPlugin = {
3
+ type: 'pwa',
4
+ injectProject: (ctx) => injectPwaProject(ctx),
5
+ };
6
+ export { injectPwaProject } from './inject-project.js';
7
+ export { buildMaysonServiceWorkerRegisterSource } from './templates/service-worker-register.js';
8
+ export { buildMaysonInstallPromptSource } from './templates/install-prompt.js';
9
+ export { buildManifestSource } from './templates/manifest.js';
10
+ export { buildSwJsSource } from './templates/sw.js.js';
11
+ export { patchLayoutPwaMetadata } from './patch-layout-metadata.js';
@@ -0,0 +1,4 @@
1
+ import type { ProjectInjectContext, ProjectInjectResult } from '../../core/types.js';
2
+ /** Orchestrate all PWA project-level writes + layout inject for SW/install components. */
3
+ export declare function injectPwaProject(ctx: ProjectInjectContext): ProjectInjectResult;
4
+ //# sourceMappingURL=inject-project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-project.d.ts","sourceRoot":"","sources":["../../../src/plugins/pwa/inject-project.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAuI7B,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,oBAAoB,GAAG,mBAAmB,CAmE/E"}