@mayson-org/inject-script 1.0.7 → 1.0.8

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.
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Remove a previously injected Mayson component from the root layout
3
+ * (import, JSX tag, and injection comment).
4
+ */
5
+ export declare function removeComponentFromLayout(filePath: string, componentName: string, dryRun?: boolean): boolean;
6
+ /** Delete generated component file next to the layout (e.g. MaysonWatermark.tsx). */
7
+ export declare function deleteGeneratedComponentFile(layoutPath: string, componentName: string, dryRun?: boolean): boolean;
8
+ //# sourceMappingURL=remove-component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remove-component.d.ts","sourceRoot":"","sources":["../../src/core/remove-component.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,MAAM,UAAQ,GACb,OAAO,CAiCT;AAED,qFAAqF;AACrF,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,MAAM,UAAQ,GACb,OAAO,CAkBT"}
@@ -0,0 +1,44 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ /**
4
+ * Remove a previously injected Mayson component from the root layout
5
+ * (import, JSX tag, and injection comment).
6
+ */
7
+ export function removeComponentFromLayout(filePath, componentName, dryRun = false) {
8
+ if (!fs.existsSync(filePath)) {
9
+ return false;
10
+ }
11
+ const before = fs.readFileSync(filePath, 'utf-8');
12
+ let content = before;
13
+ content = content.replace(new RegExp(`^import\\s*\\{\\s*${componentName}\\s*\\}\\s*from\\s*['"][^'"]+['"];?\\s*\\n?`, 'gm'), '');
14
+ content = content.replace(new RegExp(`\\n?\\s*\\{/\\*\\s*@mayson-component-injected:\\s*${componentName}\\s*\\*/\\}\\s*\\n?\\s*<${componentName}\\s*/>\\s*`, 'g'), '\n');
15
+ // Fallback if comment was removed but tag remains
16
+ content = content.replace(new RegExp(`\\n?\\s*<${componentName}\\s*/>\\s*`, 'g'), '\n');
17
+ if (content === before) {
18
+ return false;
19
+ }
20
+ if (!dryRun) {
21
+ fs.writeFileSync(filePath, content, 'utf-8');
22
+ }
23
+ return true;
24
+ }
25
+ /** Delete generated component file next to the layout (e.g. MaysonWatermark.tsx). */
26
+ export function deleteGeneratedComponentFile(layoutPath, componentName, dryRun = false) {
27
+ const dir = path.dirname(layoutPath);
28
+ const candidates = [
29
+ path.join(dir, `${componentName}.tsx`),
30
+ path.join(dir, `${componentName}.jsx`),
31
+ path.join(dir, `${componentName}.ts`),
32
+ path.join(dir, `${componentName}.js`),
33
+ ];
34
+ let deleted = false;
35
+ for (const filePath of candidates) {
36
+ if (!fs.existsSync(filePath))
37
+ continue;
38
+ if (!dryRun) {
39
+ fs.unlinkSync(filePath);
40
+ }
41
+ deleted = true;
42
+ }
43
+ return deleted;
44
+ }
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import type { ComponentType, InjectorResult } from './core/types.js';
2
2
  export { findRootLayout } from './core/find-root-layout.js';
3
3
  export { generateComponents } from './core/generators.js';
4
4
  export { injectComponentsIntoLayout } from './core/injector.js';
5
+ export { deleteGeneratedComponentFile, removeComponentFromLayout, } from './core/remove-component.js';
5
6
  export { buildRemixRedirectUrl, BADGE_UTM_SOURCE } from './shared/remix-url.js';
6
7
  export type { RemixUrlConfig } from './shared/remix-url.js';
7
8
  export { loadMaysonEnvConfig } from './shared/config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,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,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;AAwBzB;;;GAGG;AACH,wBAAsB,aAAa,CACjC,WAAW,GAAE,MAAsB,EACnC,KAAK,GAAE,aAAa,EAA2B,EAC/C,MAAM,GAAE,OAAe,GACtB,OAAO,CAAC,cAAc,CAAC,CA0DzB"}
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"}
package/dist/index.js CHANGED
@@ -2,10 +2,12 @@ import path from 'node:path';
2
2
  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
+ import { deleteGeneratedComponentFile, removeComponentFromLayout, } from './core/remove-component.js';
5
6
  import { resolveMaysonConfig } from './shared/generated-app-metadata.js';
6
7
  export { findRootLayout } from './core/find-root-layout.js';
7
8
  export { generateComponents } from './core/generators.js';
8
9
  export { injectComponentsIntoLayout } from './core/injector.js';
10
+ export { deleteGeneratedComponentFile, removeComponentFromLayout, } from './core/remove-component.js';
9
11
  export { buildRemixRedirectUrl, BADGE_UTM_SOURCE } from './shared/remix-url.js';
10
12
  export { loadMaysonEnvConfig } from './shared/config.js';
11
13
  export { fetchGeneratedAppMetadata, resolveMaysonConfig, shouldFetchGeneratedAppMetadata, } from './shared/generated-app-metadata.js';
@@ -18,13 +20,23 @@ function filterTypesForConfig(types, showRemixPill) {
18
20
  ? ['watermark', 'ascii', 'metadata']
19
21
  : types;
20
22
  if (selected.includes('watermark') && !showRemixPill) {
21
- messages.push('watermark skipped — show_remix_pill is false (set via generated-app-metadata API)');
23
+ messages.push('watermark disabled — show_remix_pill is false (removing pill if present)');
22
24
  return {
23
25
  types: selected.filter((t) => t !== 'watermark'),
24
26
  messages,
27
+ removeWatermark: true,
25
28
  };
26
29
  }
27
- return { types: selected, messages };
30
+ return { types: selected, messages, removeWatermark: false };
31
+ }
32
+ function stripWatermark(layoutPath, dryRun, messages) {
33
+ const removedFromLayout = removeComponentFromLayout(layoutPath, 'MaysonWatermark', dryRun);
34
+ const deletedFile = deleteGeneratedComponentFile(layoutPath, 'MaysonWatermark', dryRun);
35
+ if (removedFromLayout || deletedFile) {
36
+ messages.push(dryRun
37
+ ? 'would remove MaysonWatermark from layout / disk'
38
+ : 'removed MaysonWatermark from layout / disk');
39
+ }
28
40
  }
29
41
  /**
30
42
  * Auto-detect root layout, fetch watermark flags from generated-app-metadata when
@@ -42,7 +54,11 @@ export async function runAutoInject(projectRoot = process.cwd(), types = ['water
42
54
  };
43
55
  }
44
56
  const config = await resolveMaysonConfig();
45
- const { types: effectiveTypes, messages } = filterTypesForConfig(types, config.showRemixPill);
57
+ console.log(`[mayson] resolved show_remix_pill=${config.showRemixPill} enable_remix=${config.enableRemix}`);
58
+ const { types: effectiveTypes, messages, removeWatermark } = filterTypesForConfig(types, config.showRemixPill);
59
+ if (removeWatermark) {
60
+ stripWatermark(layoutPath, dryRun, messages);
61
+ }
46
62
  if (effectiveTypes.length === 0) {
47
63
  return {
48
64
  success: true,
@@ -1 +1 @@
1
- {"version":3,"file":"generated-app-metadata.d.ts","sourceRoot":"","sources":["../../src/shared/generated-app-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,yBAAyB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,EAAE,IAAI,CAC5C,eAAe,EACf,eAAe,GAAG,aAAa,CAIhC,CAAC;AAEF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,aAAa,GAAG,cAAc,CAAC,GAC3E,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAGT;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC,CAWjE;AAED,6EAA6E;AAC7E,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,4BAA4B,GAAG,IAAI,GAAG,SAAS,GACpD,OAAO,CAiBT;AAYD,6FAA6F;AAC7F,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,CAiDjF;AAED,oFAAoF;AACpF,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,eAAe,CAAC,CAa1B"}
1
+ {"version":3,"file":"generated-app-metadata.d.ts","sourceRoot":"","sources":["../../src/shared/generated-app-metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,MAAM,MAAM,yBAAyB,GAAG;IACtC,eAAe,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,yBAAyB,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,EAAE,IAAI,CAC5C,eAAe,EACf,eAAe,GAAG,aAAa,CAIhC,CAAC;AAEF,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,YAAY,GAAG,aAAa,GAAG,cAAc,CAAC,GAC3E,MAAM,GAAG,IAAI,CASf;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAGT;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC,CAajE;AAeD,6EAA6E;AAC7E,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,4BAA4B,GAAG,IAAI,GAAG,SAAS,GACpD,OAAO,CAiBT;AAYD,6FAA6F;AAC7F,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE,eAAe,GAAG,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,CAqDjF;AAED,oFAAoF;AACpF,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,eAAe,CAAC,CAa1B"}
@@ -19,14 +19,28 @@ export function shouldFetchGeneratedAppMetadata(config, webToken) {
19
19
  }
20
20
  export function mapGeneratedAppMetadataValue(value) {
21
21
  const partial = {};
22
- if (value.show_remix_pill !== null && value.show_remix_pill !== undefined) {
23
- partial.showRemixPill = value.show_remix_pill;
22
+ const show = coerceBoolean(value.show_remix_pill);
23
+ if (show !== undefined) {
24
+ partial.showRemixPill = show;
24
25
  }
25
- if (value.enable_remix !== null && value.enable_remix !== undefined) {
26
- partial.enableRemix = value.enable_remix;
26
+ const remix = coerceBoolean(value.enable_remix);
27
+ if (remix !== undefined) {
28
+ partial.enableRemix = remix;
27
29
  }
28
30
  return partial;
29
31
  }
32
+ function coerceBoolean(value) {
33
+ if (typeof value === 'boolean') {
34
+ return value;
35
+ }
36
+ if (value === 'true' || value === 1 || value === '1') {
37
+ return true;
38
+ }
39
+ if (value === 'false' || value === 0 || value === '0') {
40
+ return false;
41
+ }
42
+ return undefined;
43
+ }
30
44
  /** True when API indicates no metadata row exists yet (HTTP or body 404). */
31
45
  export function isGeneratedAppMetadataNotFound(httpStatus, data) {
32
46
  if (httpStatus === 404) {
@@ -82,7 +96,9 @@ export async function fetchGeneratedAppMetadata(config, options = {}) {
82
96
  console.warn('[mayson] generated-app-metadata response invalid — using local config');
83
97
  return null;
84
98
  }
85
- return mapGeneratedAppMetadataValue(data.value);
99
+ const mapped = mapGeneratedAppMetadataValue(data.value);
100
+ console.log(`[mayson] generated-app-metadata ok — show_remix_pill=${String(mapped.showRemixPill)} enable_remix=${String(mapped.enableRemix)}`);
101
+ return mapped;
86
102
  }
87
103
  catch (err) {
88
104
  console.warn(`[mayson] generated-app-metadata fetch failed: ${err.message} — using local config`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mayson-org/inject-script",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "CLI and library to inject Mayson watermark and ascii into Next.js App Router layouts.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",