@c15t/cli 1.6.1 → 1.7.0-canary-20251012181938

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.
@@ -1 +1 @@
1
- {"version":3,"file":"generate-files.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/options/utils/generate-files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACxD,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAgMD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EACnC,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,WAAW,EACX,UAAU,GACV,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgErD"}
1
+ {"version":3,"file":"generate-files.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/options/utils/generate-files.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAUlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACxD,OAAO,EAAE,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACpC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAqOD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,EACnC,OAAO,EACP,IAAI,EACJ,OAAO,EACP,UAAU,EACV,WAAW,EACX,UAAU,GACV,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiErD"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,SAAS,GAChB,MAAM,CAiGR"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAC1C,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,EACpB,MAAM,CAAC,EAAE,SAAS,GAChB,MAAM,CAuER"}
@@ -12,10 +12,14 @@ interface UpdateReactLayoutOptions {
12
12
  pkg: AvailablePackages;
13
13
  proxyNextjs?: boolean;
14
14
  }
15
+ interface ComponentFilePaths {
16
+ consentManager: string;
17
+ }
15
18
  export declare function updateReactLayout(options: UpdateReactLayoutOptions): Promise<{
16
19
  updated: boolean;
17
20
  filePath: string | null;
18
21
  alreadyModified: boolean;
22
+ componentFiles?: ComponentFilePaths;
19
23
  }>;
20
24
  export {};
21
25
  //# sourceMappingURL=layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAQvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAwQD,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,wBAAwB,GAC/B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC,CAiBD"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../src/commands/generate/templates/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAKvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;CACvB;AA2UD,wBAAsB,iBAAiB,CACtC,OAAO,EAAE,wBAAwB,GAC/B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CAkBD"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Component template generators for Next.js App Directory
3
+ * Generates consent-manager.tsx and consent-manager.client.tsx components
4
+ */
5
+ /**
6
+ * Generates the server-side consent-manager.tsx component template
7
+ *
8
+ * @param optionsText - The stringified options object for ConsentManagerProvider
9
+ * @returns The complete component file content
10
+ *
11
+ * @remarks
12
+ * This component is rendered on the server and contains:
13
+ * - ConsentManagerProvider with server-side configuration
14
+ * - CookieBanner component
15
+ * - ConsentManagerDialog component
16
+ * - ConsentManagerClient wrapper for client-side features
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "/api/c15t" }');
21
+ * ```
22
+ */
23
+ export declare function generateConsentManagerTemplate(optionsText: string): string;
24
+ /**
25
+ * Generates the client-side consent-manager.client.tsx component template
26
+ *
27
+ * @returns The complete client component file content
28
+ *
29
+ * @remarks
30
+ * This component is marked with 'use client' directive and handles:
31
+ * - ClientSideOptionsProvider for callbacks and scripts
32
+ * - Integration scripts (Google Tag Manager, Meta Pixel, etc.)
33
+ * - Client-side callbacks (onConsentSet, onError, etc.)
34
+ *
35
+ * Users should customize this file to add their specific scripts and callbacks.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const content = generateConsentManagerClientTemplate();
40
+ * await fs.writeFile('consent-manager.client.tsx', content);
41
+ * ```
42
+ */
43
+ export declare function generateConsentManagerClientTemplate(): string;
44
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA4D1E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oCAAoC,IAAI,MAAM,CAyD7D"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * App Directory layout template generator
3
3
  * Handles updating Next.js App Directory layout files with ConsentManagerProvider
4
+ * and creates separate consent-manager component files
4
5
  */
5
6
  import type { AvailablePackages } from '../../../../../context/framework-detection';
6
7
  interface UpdateAppLayoutOptions {
@@ -11,10 +12,31 @@ interface UpdateAppLayoutOptions {
11
12
  pkg: AvailablePackages;
12
13
  proxyNextjs?: boolean;
13
14
  }
14
- export declare function updateAppLayout({ projectRoot, mode, pkg, backendURL, useEnvFile, proxyNextjs, }: UpdateAppLayoutOptions): Promise<{
15
+ interface ComponentFilePaths {
16
+ consentManager: string;
17
+ consentManagerClient: string;
18
+ }
19
+ /**
20
+ * Updates Next.js App Directory layout with consent management components
21
+ *
22
+ * @param options - Configuration options for the update
23
+ * @returns Information about the update operation including file paths
24
+ *
25
+ * @throws {Error} When component files cannot be created or layout cannot be updated
26
+ *
27
+ * @remarks
28
+ * This function performs the following steps:
29
+ * 1. Locates the App Directory layout file
30
+ * 2. Checks if consent management is already configured
31
+ * 3. Creates consent-manager.tsx and consent-manager.client.tsx files
32
+ * 4. Adds ConsentManager import to layout
33
+ * 5. Wraps layout content with ConsentManager component
34
+ */
35
+ export declare function updateAppLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs, }: UpdateAppLayoutOptions): Promise<{
15
36
  updated: boolean;
16
37
  filePath: string | null;
17
38
  alreadyModified: boolean;
39
+ componentFiles?: ComponentFilePaths;
18
40
  }>;
19
41
  export {};
20
42
  //# sourceMappingURL=layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAYvE,UAAU,sBAAsB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAkHD,wBAAsB,eAAe,CAAC,EACrC,WAAW,EACX,IAAI,EACJ,GAAG,EACH,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,sBAAsB,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC,CA2DD"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/app/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAYvE,UAAU,sBAAsB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,oBAAoB,EAAE,MAAM,CAAC;CAC7B;AAgQD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,EACrC,WAAW,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,sBAAsB,GAAG,OAAO,CAAC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CA6ED"}
@@ -18,6 +18,10 @@ export declare function updateNextLayout(options: UpdateNextLayoutOptions): Prom
18
18
  filePath: string | null;
19
19
  alreadyModified: boolean;
20
20
  structureType: NextStructure;
21
+ componentFiles?: {
22
+ consentManager: string;
23
+ consentManagerClient?: string;
24
+ };
21
25
  }>;
22
26
  export {};
23
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/next/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,uBAAuB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;AAsC5C,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;CAC7B,CAAC,CA4BD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/next/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,uBAAuB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,KAAK,aAAa,GAAG,KAAK,GAAG,OAAO,GAAG,IAAI,CAAC;AAsC5C,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC;IACV,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,CAAC,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;KAC9B,CAAC;CACF,CAAC,CAgCD"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Component template generators for Next.js Pages Directory
3
+ * Generates consent-manager.tsx component
4
+ */
5
+ /**
6
+ * Generates the consent-manager.tsx component template for Pages Directory
7
+ *
8
+ * @param optionsText - The stringified options object for ConsentManagerProvider
9
+ * @returns The complete component file content
10
+ *
11
+ * @remarks
12
+ * This component wraps the Pages Directory app with consent management.
13
+ * Unlike App Directory, Pages Directory doesn't need a separate client component
14
+ * because it doesn't use the 'use client' directive pattern.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "/api/c15t" }');
19
+ * ```
20
+ */
21
+ export declare function generateConsentManagerTemplate(optionsText: string): string;
22
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA+D1E"}
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Pages Directory layout template generator
3
3
  * Handles updating Next.js Pages Directory _app.tsx files with ConsentManagerProvider
4
+ * and creates separate consent-manager component files
4
5
  */
5
6
  import type { AvailablePackages } from '../../../../../context/framework-detection';
6
7
  interface UpdatePagesLayoutOptions {
@@ -11,10 +12,34 @@ interface UpdatePagesLayoutOptions {
11
12
  pkg: AvailablePackages;
12
13
  proxyNextjs?: boolean;
13
14
  }
14
- export declare function updatePagesLayout({ projectRoot, mode, pkg, backendURL, useEnvFile, proxyNextjs, }: UpdatePagesLayoutOptions): Promise<{
15
+ interface ComponentFilePaths {
16
+ consentManager: string;
17
+ }
18
+ /**
19
+ * Updates Next.js Pages Directory _app with consent management component
20
+ *
21
+ * @param options - Configuration options for the update
22
+ * @returns Information about the update operation including file paths
23
+ *
24
+ * @throws {Error} When component file cannot be created or _app cannot be updated
25
+ *
26
+ * @remarks
27
+ * This function performs the following steps:
28
+ * 1. Locates the Pages Directory _app file
29
+ * 2. Checks if consent management is already configured
30
+ * 3. Creates consent-manager.tsx file
31
+ * 4. Adds ConsentManager import to _app
32
+ * 5. Wraps _app content with ConsentManager component
33
+ * 6. Adds helpful comment about withInitialC15TData
34
+ *
35
+ * Unlike App Directory, Pages Directory only needs one component file because
36
+ * it doesn't use the 'use client' directive pattern.
37
+ */
38
+ export declare function updatePagesLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs, }: UpdatePagesLayoutOptions): Promise<{
15
39
  updated: boolean;
16
40
  filePath: string | null;
17
41
  alreadyModified: boolean;
42
+ componentFiles?: ComponentFilePaths;
18
43
  }>;
19
44
  export {};
20
45
  //# sourceMappingURL=layout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/layout.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAOvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAyJD,wBAAsB,iBAAiB,CAAC,EACvC,WAAW,EACX,IAAI,EACJ,GAAG,EACH,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,wBAAwB,GAAG,OAAO,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CACzB,CAAC,CAgED"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../../src/commands/generate/templates/next/pages/layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAIvE,UAAU,wBAAwB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,EAAE,iBAAiB,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,kBAAkB;IAC3B,cAAc,EAAE,MAAM,CAAC;CACvB;AAqRD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,iBAAiB,CAAC,EACvC,WAAW,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,WAAW,GACX,EAAE,wBAAwB,GAAG,OAAO,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACpC,CAAC,CA+ED"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Component template generators for React
3
+ * Generates consent-manager.tsx component
4
+ */
5
+ /**
6
+ * Generates the consent-manager.tsx component template for React
7
+ *
8
+ * @param optionsText - The stringified options object for ConsentManagerProvider
9
+ * @returns The complete component file content
10
+ *
11
+ * @remarks
12
+ * This component wraps the React app with consent management.
13
+ * Since React is client-only, we don't need to worry about SSR or separate client components.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const content = generateConsentManagerTemplate('{ mode: "c15t", backendURL: "https://your-instance.c15t.dev" }');
18
+ * ```
19
+ */
20
+ export declare function generateConsentManagerTemplate(optionsText: string): string;
21
+ //# sourceMappingURL=components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../../src/commands/generate/templates/react/components.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6C1E"}
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import * as __WEBPACK_EXTERNAL_MODULE_node_os_74b4b876__ from "node:os";
10
10
  import * as __WEBPACK_EXTERNAL_MODULE_posthog_node_1b07bdf4__ from "posthog-node";
11
11
  import * as __WEBPACK_EXTERNAL_MODULE_node_child_process_27f17141__ from "node:child_process";
12
12
  import * as __WEBPACK_EXTERNAL_MODULE_node_events_0a6aefe7__ from "node:events";
13
- import * as __WEBPACK_EXTERNAL_MODULE__doubletie_logger_91c58a8f__ from "@doubletie/logger";
13
+ import * as __WEBPACK_EXTERNAL_MODULE__c15t_logger_04a510d4__ from "@c15t/logger";
14
14
  import * as __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__ from "ts-morph";
15
15
  import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_migrator_64e67b79__ from "@c15t/backend/v2/db/migrator";
16
16
  import * as __WEBPACK_EXTERNAL_MODULE__c15t_backend_v2_db_schema_c18e255b__ from "@c15t/backend/v2/db/schema";
@@ -499,7 +499,7 @@ const logMessage = (logLevel, message, ...args)=>{
499
499
  }
500
500
  };
501
501
  const createCliLogger = (level)=>{
502
- const baseLogger = (0, __WEBPACK_EXTERNAL_MODULE__doubletie_logger_91c58a8f__.createLogger)({
502
+ const baseLogger = (0, __WEBPACK_EXTERNAL_MODULE__c15t_logger_04a510d4__.createLogger)({
503
503
  level,
504
504
  appName: 'c15t',
505
505
  log: (logLevel, message, ...args)=>{
@@ -538,82 +538,56 @@ function generateClientConfigContent(mode, backendURL, useEnvFile, logger) {
538
538
  ];
539
539
  switch(mode){
540
540
  case 'c15t':
541
- configContent = `// c15t Client Configuration
542
- import type { ConsentManagerOptions } from '@c15t/react';
541
+ configContent = `
542
+ import {
543
+ type ConsentManagerOptions,
544
+ configureConsentManager,
545
+ createConsentManagerStore
546
+ } from "c15t";
543
547
 
544
- export const c15tConfig = {
545
- // Using hosted c15t (consent.io) or self-hosted instance
546
- mode: 'c15t',
547
- backendURL: ${useEnvFile ? 'process.env.NEXT_PUBLIC_C15T_URL' : `'${backendURL || 'https://your-instance.c15t.dev'}'`},
548
- consentCategories: ['necessary', 'marketing'], // Optional: Specify which consent categories to show in the banner.
549
- ignoreGeoLocation: true, // Useful for development to always view the banner.
550
-
551
- // Optional: Add callback functions for various events
552
- callbacks: {
553
- onConsentSet: (response) => {
554
- console.log('Consent has been saved');
555
- }
556
- }
557
- } satisfies ConsentManagerOptions;
548
+ export const consentManager = configureConsentManager({ mode: "c15t", backendURL: ${useEnvFile ? 'process.env.NEXT_PUBLIC_C15T_URL' : `'${backendURL || 'https://your-instance.c15t.dev'}'`}, });
549
+ export const store = createConsentManagerStore(consentManager, {
550
+ initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
551
+ ignoreGeoLocation: true // Useful for development to always view the banner.
552
+ });
558
553
 
559
- // Use in your app layout:
560
- // <ConsentManagerProvider options={c15tConfig}>
561
- // {children}
562
- // <CookieBanner />
563
- // <ConsentManagerDialog />
564
- // </ConsentManagerProvider>
554
+ store.getState().setConsent("marketing", true); // set consent to marketing
555
+ store.getState().showPopup;
565
556
  `;
566
557
  break;
567
558
  case 'offline':
568
- configContent = `// c15t Client Configuration
569
- import type { ConsentManagerOptions } from '@c15t/react';
559
+ configContent = `
560
+ import {
561
+ type ConsentManagerOptions,
562
+ configureConsentManager,
563
+ createConsentManagerStore
564
+ } from "c15t";
570
565
 
571
- export const c15tConfig = {
572
- // Using offline mode for browser-based storage
573
- mode: 'offline',
574
-
575
- // Optional: Add callback functions for various events
576
- callbacks: {
577
- onConsentSet: (response) => {
578
- console.log('Consent has been saved locally');
579
- }
580
- }
581
- } satisfies ConsentManagerOptions;
566
+ export const consentManager = configureConsentManager({ mode: "offline" });
567
+ export const store = createConsentManagerStore(consentManager, {
568
+ initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
569
+ });
582
570
 
583
- // Use in your app layout:
584
- // <ConsentManagerProvider options={c15tConfig}>
585
- // {children}
586
- // <CookieBanner />
587
- // <ConsentManagerDialog />
588
- // </ConsentManagerProvider>
571
+ store.getState().setConsent("marketing", true); // set consent to marketing
572
+ store.getState().showPopup; // should show popup?
573
+
589
574
  `;
590
575
  break;
591
576
  case 'custom':
592
- configContent = `// c15t Client Configuration
593
- import type { ConsentManagerOptions } from '@c15t/react';
594
- import { createCustomHandlers } from './consent-handlers';
577
+ configContent = `import {
578
+ type ConsentManagerOptions,
579
+ configureConsentManager,
580
+ createConsentManagerStore
581
+ } from "c15t";
595
582
 
596
- export const c15tConfig = {
597
- // Using custom mode for complete control
598
- mode: 'custom',
599
- endpointHandlers: createCustomHandlers(),
600
-
601
- // Optional: Add callback functions for various events
602
- callbacks: {
603
- onConsentSet: (response) => {
604
- console.log('Consent has been saved');
605
- }
606
- }
607
- } satisfies ConsentManagerOptions;
608
-
609
- // Use in your app layout:
610
- // <ConsentManagerProvider options={c15tConfig}>
611
- // {children}
612
- // <CookieBanner />
613
- // <ConsentManagerDialog />
614
- // </ConsentManagerProvider>
583
+ export const consentManager = configureConsentManager({ mode: "custom", endpointHandlers: createCustomHandlers(), });
584
+ export const store = createConsentManagerStore(consentManager, {
585
+ initialGdprTypes: ["necessary", "marketing"], // Optional: Specify which consent categories to show in the banner.
586
+ ignoreGeoLocation: true // Useful for development to always view the banner.
587
+ });
615
588
 
616
- // Don't forget to implement your custom handlers in consent-handlers.ts!
589
+ store.getState().setConsent("marketing", true); // set consent to marketing
590
+ store.getState().showPopup; // should show popup?
617
591
  `;
618
592
  break;
619
593
  default:
@@ -665,21 +639,124 @@ function generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs) {
665
639
  }`;
666
640
  }
667
641
  }
668
- function getBaseImports() {
669
- return [
670
- 'CookieBanner',
671
- 'ConsentManagerDialog'
672
- ];
642
+ function generateConsentManagerTemplate(optionsText) {
643
+ return `import type { ReactNode } from 'react';
644
+ import {
645
+ ConsentManagerDialog,
646
+ ConsentManagerProvider,
647
+ CookieBanner,
648
+ } from '@c15t/nextjs';
649
+ // For client-only apps (non-SSR), you can use:
650
+ // import { ConsentManagerProvider } from '@c15t/nextjs/client';
651
+ import { ConsentManagerClient } from './consent-manager.client';
652
+
653
+ /**
654
+ * Server-side rendered consent management wrapper for Next.js App Router
655
+ *
656
+ * This component provides SSR-compatible consent management by separating
657
+ * server-side configuration from client-side functionality. The server handles
658
+ * initial setup and configuration, while client-side features (callbacks,
659
+ * scripts) are delegated to the ConsentManagerClient component.
660
+ *
661
+ * @param props - Component properties
662
+ * @param props.children - Child components to render within the consent manager context
663
+ *
664
+ * @returns The consent manager provider with banner, dialog, and client wrapper
665
+ *
666
+ * @remarks
667
+ * This split architecture is necessary because certain options like callbacks
668
+ * and scripts cannot be serialized during server-side rendering. For
669
+ * client-only implementations, use \`<ConsentManagerProvider />\` from
670
+ * \`@c15t/nextjs/client\`.
671
+ *
672
+ * @example
673
+ * \`\`\`tsx
674
+ * // In your root layout.tsx
675
+ * import { ConsentManager } from './consent-manager';
676
+ *
677
+ * export default function RootLayout({ children }) {
678
+ * return (
679
+ * <html>
680
+ * <body>
681
+ * <ConsentManager>
682
+ * {children}
683
+ * </ConsentManager>
684
+ * </body>
685
+ * </html>
686
+ * );
687
+ * }
688
+ * \`\`\`
689
+ */
690
+ export function ConsentManager({ children }: { children: ReactNode }) {
691
+ return (
692
+ <ConsentManagerProvider
693
+ options={${optionsText}}
694
+ >
695
+ <CookieBanner />
696
+ <ConsentManagerDialog />
697
+ <ConsentManagerClient>{children}</ConsentManagerClient>
698
+ </ConsentManagerProvider>
699
+ );
673
700
  }
674
- function getCustomModeImports() {
675
- return [
676
- {
677
- namedImports: [
678
- 'createCustomHandlers'
679
- ],
680
- moduleSpecifier: './consent-handlers'
681
- }
682
- ];
701
+ `;
702
+ }
703
+ function generateConsentManagerClientTemplate() {
704
+ return `'use client';
705
+
706
+ import type { ReactNode } from 'react';
707
+ import { ClientSideOptionsProvider } from '@c15t/nextjs/client';
708
+
709
+ /**
710
+ * Client-side consent manager wrapper for handling scripts and callbacks
711
+ *
712
+ * This component is rendered on the client and provides the ability to:
713
+ * - Load integration scripts (Google Tag Manager, Meta Pixel, TikTok Pixel, etc.)
714
+ * - Handle client-side callbacks (onConsentSet, onError, onBannerFetched)
715
+ * - Manage script lifecycle (onLoad, onDelete)
716
+ *
717
+ * @param props - Component properties
718
+ * @param props.children - Child components to render within the client-side context
719
+ *
720
+ * @returns The client-side options provider with children
721
+ *
722
+ * @see https://c15t.com/docs/frameworks/next/callbacks
723
+ * @see https://c15t.com/docs/frameworks/next/script-loader
724
+ */
725
+ export function ConsentManagerClient({
726
+ children,
727
+ }: {
728
+ children: ReactNode;
729
+ }) {
730
+ return (
731
+ <ClientSideOptionsProvider
732
+ // 📝 Add your integration scripts here
733
+ // Scripts are loaded when consent is given and removed when consent is revoked
734
+ scripts={[
735
+ // Example:
736
+ // googleTagManager({
737
+ // id: 'GTM-XXXXXX',
738
+ // script: {
739
+ // onLoad: () => console.log('GTM loaded'),
740
+ // },
741
+ // }),
742
+ ]}
743
+ // 📝 Add your callbacks here
744
+ // Callbacks allow you to react to consent events
745
+ callbacks={{
746
+ // Example:
747
+ // onConsentSet(response) {
748
+ // console.log('Consent updated:', response);
749
+ // },
750
+ // onError(error) {
751
+ // console.error('Consent error:', error);
752
+ // },
753
+ }}
754
+ >
755
+ {children}
756
+ </ClientSideOptionsProvider>
757
+ );
758
+ }
759
+ `;
683
760
  }
684
761
  const HTML_TAG_REGEX = /<html[^>]*>([\s\S]*)<\/html>/;
685
762
  const BODY_TAG_REGEX = /<body[^>]*>([\s\S]*)<\/body>/;
@@ -697,55 +774,78 @@ function findAppLayoutFile(project, projectRoot) {
697
774
  if (files.length > 0) return files[0];
698
775
  }
699
776
  }
700
- function updateAppImports(layoutFile, packageName, mode) {
701
- const requiredImports = [
702
- 'ConsentManagerProvider',
703
- ...getBaseImports()
704
- ];
705
- let hasC15tImport = false;
706
- for (const importDecl of layoutFile.getImportDeclarations())if (importDecl.getModuleSpecifierValue() === packageName) {
707
- hasC15tImport = true;
708
- const namedImports = importDecl.getNamedImports().map((i)=>i.getName());
709
- const missingImports = requiredImports.filter((imp)=>!namedImports.includes(imp));
710
- if (missingImports.length > 0) importDecl.addNamedImports(missingImports);
711
- break;
712
- }
713
- if (!hasC15tImport) layoutFile.addImportDeclaration({
714
- namedImports: requiredImports,
715
- moduleSpecifier: packageName
777
+ function getAppDirectory(layoutFilePath) {
778
+ const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(layoutFilePath);
779
+ const srcAppSegment = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'app');
780
+ if (normalizedPath.includes(srcAppSegment)) return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'app');
781
+ return 'app';
782
+ }
783
+ function computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
784
+ const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
785
+ let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
786
+ relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
787
+ relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
788
+ if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
789
+ return relativePath;
790
+ }
791
+ function addConsentManagerImport(layoutFile, consentManagerFilePath) {
792
+ const layoutFilePath = layoutFile.getFilePath();
793
+ const moduleSpecifier = computeRelativeModuleSpecifier(layoutFilePath, consentManagerFilePath);
794
+ const existingImports = layoutFile.getImportDeclarations();
795
+ const hasConsentManagerImport = existingImports.some((importDecl)=>{
796
+ const existingSpec = importDecl.getModuleSpecifierValue();
797
+ return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
798
+ });
799
+ if (!hasConsentManagerImport) layoutFile.addImportDeclaration({
800
+ namedImports: [
801
+ 'ConsentManager'
802
+ ],
803
+ moduleSpecifier
716
804
  });
717
- if ('custom' === mode) for (const customImport of getCustomModeImports())layoutFile.addImportDeclaration(customImport);
718
805
  }
719
- function wrapAppJsxContent(originalJsx, optionsText) {
806
+ function wrapAppJsxContent(originalJsx) {
720
807
  const hasHtmlTag = originalJsx.includes('<html') || originalJsx.includes('</html>');
721
808
  const hasBodyTag = originalJsx.includes('<body') || originalJsx.includes('</body>');
722
- const providerWrapper = (content)=>`
723
- <ConsentManagerProvider options={${optionsText}}>
724
- <CookieBanner />
725
- <ConsentManagerDialog />
809
+ const consentWrapper = (content)=>`
810
+ <ConsentManager>
726
811
  ${content}
727
- </ConsentManagerProvider>
812
+ </ConsentManager>
728
813
  `;
729
814
  if (hasHtmlTag) {
730
815
  const htmlMatch = originalJsx.match(HTML_TAG_REGEX);
731
816
  const htmlContent = htmlMatch?.[1] || '';
732
- if (!htmlContent) return providerWrapper(originalJsx);
817
+ if (!htmlContent) return consentWrapper(originalJsx);
733
818
  const bodyMatch = htmlContent.match(BODY_TAG_REGEX);
734
- if (!bodyMatch) return originalJsx.replace(HTML_CONTENT_REGEX, `<html>${providerWrapper('$1')}</html>`);
819
+ if (!bodyMatch) return originalJsx.replace(HTML_CONTENT_REGEX, `<html>${consentWrapper('$1')}</html>`);
735
820
  const bodyContent = bodyMatch[1] || '';
736
821
  const bodyOpeningTag = originalJsx.match(BODY_OPENING_TAG_REGEX)?.[0] || '<body>';
737
- return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${providerWrapper(bodyContent)}</body>`);
822
+ return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${consentWrapper(bodyContent)}</body>`);
738
823
  }
739
824
  if (hasBodyTag) {
740
825
  const bodyMatch = originalJsx.match(BODY_TAG_REGEX);
741
826
  const bodyContent = bodyMatch?.[1] || '';
742
- if (!bodyContent) return providerWrapper(originalJsx);
827
+ if (!bodyContent) return consentWrapper(originalJsx);
743
828
  const bodyOpeningTag = originalJsx.match(BODY_OPENING_TAG_REGEX)?.[0] || '<body>';
744
- return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${providerWrapper(bodyContent)}</body>`);
745
- }
746
- return providerWrapper(originalJsx);
829
+ return originalJsx.replace(BODY_TAG_REGEX, `${bodyOpeningTag}${consentWrapper(bodyContent)}</body>`);
830
+ }
831
+ return consentWrapper(originalJsx);
832
+ }
833
+ async function createConsentManagerComponents(projectRoot, appDir, optionsText) {
834
+ const appDirPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, appDir);
835
+ const consentManagerContent = generateConsentManagerTemplate(optionsText);
836
+ const consentManagerClientContent = generateConsentManagerClientTemplate();
837
+ const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(appDirPath, 'consent-manager.tsx');
838
+ const consentManagerClientPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(appDirPath, 'consent-manager.client.tsx');
839
+ await Promise.all([
840
+ __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8'),
841
+ __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerClientPath, consentManagerClientContent, 'utf-8')
842
+ ]);
843
+ return {
844
+ consentManager: consentManagerPath,
845
+ consentManagerClient: consentManagerClientPath
846
+ };
747
847
  }
748
- async function updateAppLayout({ projectRoot, mode, pkg, backendURL, useEnvFile, proxyNextjs }) {
848
+ async function updateAppLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
749
849
  const project = new __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.Project();
750
850
  const layoutFile = findAppLayoutFile(project, projectRoot);
751
851
  if (!layoutFile) return {
@@ -753,37 +853,105 @@ async function updateAppLayout({ projectRoot, mode, pkg, backendURL, useEnvFile,
753
853
  filePath: null,
754
854
  alreadyModified: false
755
855
  };
856
+ const layoutFilePath = layoutFile.getFilePath();
857
+ const appDir = getAppDirectory(layoutFilePath);
756
858
  const existingImports = layoutFile.getImportDeclarations();
757
- const hasPackageImport = existingImports.some((importDecl)=>importDecl.getModuleSpecifierValue() === pkg);
758
- if (hasPackageImport) return {
859
+ const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
860
+ if (hasConsentManagerImport) return {
759
861
  updated: false,
760
- filePath: layoutFile.getFilePath(),
862
+ filePath: layoutFilePath,
761
863
  alreadyModified: true
762
864
  };
763
- updateAppImports(layoutFile, pkg, mode);
764
865
  const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
866
+ const componentFiles = await createConsentManagerComponents(projectRoot, appDir, optionsText);
867
+ addConsentManagerImport(layoutFile, componentFiles.consentManager);
765
868
  const returnStatement = layoutFile.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
766
869
  if (!returnStatement) return {
767
870
  updated: false,
768
- filePath: layoutFile.getFilePath(),
871
+ filePath: layoutFilePath,
769
872
  alreadyModified: false
770
873
  };
771
874
  const expression = returnStatement.getExpression();
772
875
  if (!expression) return {
773
876
  updated: false,
774
- filePath: layoutFile.getFilePath(),
877
+ filePath: layoutFilePath,
775
878
  alreadyModified: false
776
879
  };
777
880
  const originalJsx = expression.getText();
778
- const newJsx = wrapAppJsxContent(originalJsx, optionsText);
881
+ const newJsx = wrapAppJsxContent(originalJsx);
779
882
  returnStatement.replaceWithText(`return ${newJsx}`);
780
883
  await layoutFile.save();
781
884
  return {
782
885
  updated: true,
783
- filePath: layoutFile.getFilePath(),
784
- alreadyModified: false
886
+ filePath: layoutFilePath,
887
+ alreadyModified: false,
888
+ componentFiles
785
889
  };
786
890
  }
891
+ function components_generateConsentManagerTemplate(optionsText) {
892
+ return `import type { ReactNode } from 'react';
893
+ import {
894
+ ConsentManagerDialog,
895
+ ConsentManagerProvider,
896
+ CookieBanner,
897
+ } from '@c15t/nextjs/pages';
898
+ // For client-only apps (non-SSR), you can use:
899
+ // import { ConsentManagerProvider } from '@c15t/nextjs/client';
900
+
901
+ /**
902
+ * Consent management wrapper for Next.js Pages Router
903
+ *
904
+ * This component wraps your app with consent management functionality,
905
+ * including the cookie banner, consent dialog, and provider.
906
+ *
907
+ * @param props - Component properties
908
+ * @param props.children - Child components to render within the consent manager context
909
+ * @param props.initialData - Initial consent data from server-side props (optional)
910
+ *
911
+ * @returns The consent manager provider with banner and dialog
912
+ *
913
+ * @remarks
914
+ * To get initial server-side data on other pages, use:
915
+ * \`\`\`tsx
916
+ * import { withInitialC15TData } from '@c15t/nextjs/pages';
917
+ *
918
+ * export const getServerSideProps = withInitialC15TData('/api/c15t');
919
+ * \`\`\`
920
+ *
921
+ * @example
922
+ * \`\`\`tsx
923
+ * // In your pages/_app.tsx
924
+ * import { ConsentManager } from './consent-manager';
925
+ *
926
+ * export default function MyApp({ Component, pageProps }) {
927
+ * return (
928
+ * <ConsentManager initialData={pageProps.initialC15TData}>
929
+ * <Component {...pageProps} />
930
+ * </ConsentManager>
931
+ * );
932
+ * }
933
+ * \`\`\`
934
+ */
935
+ export function ConsentManager({
936
+ children,
937
+ initialData,
938
+ }: {
939
+ children: ReactNode;
940
+ initialData?: unknown;
941
+ }) {
942
+ return (
943
+ <ConsentManagerProvider
944
+ initialData={initialData}
945
+ options={${optionsText}}
946
+ >
947
+ <CookieBanner />
948
+ <ConsentManagerDialog />
949
+ {children}
950
+ </ConsentManagerProvider>
951
+ );
952
+ }
953
+ `;
954
+ }
787
955
  function findPagesAppFile(project, projectRoot) {
788
956
  const appPatterns = [
789
957
  'pages/_app.tsx',
@@ -796,42 +964,55 @@ function findPagesAppFile(project, projectRoot) {
796
964
  if (files.length > 0) return files[0];
797
965
  }
798
966
  }
799
- function updatePagesImports(appFile, packageName, mode) {
800
- const requiredImports = [
801
- 'ConsentManagerProvider',
802
- ...getBaseImports()
803
- ];
804
- const pagesModuleSpecifier = `${packageName}/pages`;
805
- let hasC15tImport = false;
806
- for (const importDecl of appFile.getImportDeclarations())if (importDecl.getModuleSpecifierValue() === pagesModuleSpecifier) {
807
- hasC15tImport = true;
808
- const namedImports = importDecl.getNamedImports().map((i)=>i.getName());
809
- const missingImports = requiredImports.filter((imp)=>!namedImports.includes(imp));
810
- if (missingImports.length > 0) importDecl.addNamedImports(missingImports);
811
- break;
812
- }
813
- if (!hasC15tImport) appFile.addImportDeclaration({
814
- namedImports: requiredImports,
815
- moduleSpecifier: pagesModuleSpecifier
967
+ function getPagesDirectory(appFilePath) {
968
+ const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(appFilePath);
969
+ const srcPagesSegment = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'pages');
970
+ if (normalizedPath.includes(srcPagesSegment)) return __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join('src', 'pages');
971
+ return 'pages';
972
+ }
973
+ function layout_computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
974
+ const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
975
+ let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
976
+ relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
977
+ relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
978
+ if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
979
+ return relativePath;
980
+ }
981
+ function layout_addConsentManagerImport(appFile, consentManagerFilePath) {
982
+ const appFilePath = appFile.getFilePath();
983
+ const moduleSpecifier = layout_computeRelativeModuleSpecifier(appFilePath, consentManagerFilePath);
984
+ const existingImports = appFile.getImportDeclarations();
985
+ const hasConsentManagerImport = existingImports.some((importDecl)=>{
986
+ const existingSpec = importDecl.getModuleSpecifierValue();
987
+ return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
988
+ });
989
+ if (!hasConsentManagerImport) appFile.addImportDeclaration({
990
+ namedImports: [
991
+ 'ConsentManager'
992
+ ],
993
+ moduleSpecifier
816
994
  });
817
- if ('custom' === mode) for (const customImport of getCustomModeImports())appFile.addImportDeclaration(customImport);
818
995
  }
819
- function wrapPagesJsxContent(originalJsx, optionsText) {
996
+ function wrapPagesJsxContent(originalJsx) {
820
997
  const trimmedJsx = originalJsx.trim();
821
998
  const hasParentheses = trimmedJsx.startsWith('(') && trimmedJsx.endsWith(')');
822
999
  const cleanJsx = hasParentheses ? trimmedJsx.slice(1, -1).trim() : originalJsx;
823
1000
  const wrappedContent = `
824
- <ConsentManagerProvider
825
- initialData={pageProps.initialC15TData}
826
- options={${optionsText}}
827
- >
828
- <CookieBanner />
829
- <ConsentManagerDialog />
1001
+ <ConsentManager initialData={pageProps.initialC15TData}>
830
1002
  ${cleanJsx}
831
- </ConsentManagerProvider>
1003
+ </ConsentManager>
832
1004
  `;
833
1005
  return `(${wrappedContent})`;
834
1006
  }
1007
+ async function createConsentManagerComponent(projectRoot, pagesDir, optionsText) {
1008
+ const pagesDirPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, pagesDir);
1009
+ const consentManagerContent = components_generateConsentManagerTemplate(optionsText);
1010
+ const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(pagesDirPath, 'consent-manager.tsx');
1011
+ await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8');
1012
+ return {
1013
+ consentManager: consentManagerPath
1014
+ };
1015
+ }
835
1016
  function addServerSideDataComment(appFile, backendURL, useEnvFile, proxyNextjs) {
836
1017
  const existingComments = appFile.getLeadingCommentRanges();
837
1018
  let urlExample;
@@ -864,7 +1045,7 @@ function updateAppComponentTyping(appFile) {
864
1045
  });
865
1046
  }
866
1047
  }
867
- async function updatePagesLayout({ projectRoot, mode, pkg, backendURL, useEnvFile, proxyNextjs }) {
1048
+ async function updatePagesLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
868
1049
  const project = new __WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.Project();
869
1050
  const appFile = findPagesAppFile(project, projectRoot);
870
1051
  if (!appFile) return {
@@ -872,38 +1053,41 @@ async function updatePagesLayout({ projectRoot, mode, pkg, backendURL, useEnvFil
872
1053
  filePath: null,
873
1054
  alreadyModified: false
874
1055
  };
1056
+ const appFilePath = appFile.getFilePath();
1057
+ const pagesDir = getPagesDirectory(appFilePath);
875
1058
  const existingImports = appFile.getImportDeclarations();
876
- const pagesModuleSpecifier = `${pkg}/pages`;
877
- const hasPackageImport = existingImports.some((importDecl)=>importDecl.getModuleSpecifierValue() === pagesModuleSpecifier);
878
- if (hasPackageImport) return {
1059
+ const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
1060
+ if (hasConsentManagerImport) return {
879
1061
  updated: false,
880
- filePath: appFile.getFilePath(),
1062
+ filePath: appFilePath,
881
1063
  alreadyModified: true
882
1064
  };
883
- updatePagesImports(appFile, pkg, mode);
1065
+ const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
1066
+ const componentFiles = await createConsentManagerComponent(projectRoot, pagesDir, optionsText);
1067
+ layout_addConsentManagerImport(appFile, componentFiles.consentManager);
884
1068
  updateAppComponentTyping(appFile);
885
1069
  addServerSideDataComment(appFile, backendURL, useEnvFile, proxyNextjs);
886
- const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
887
1070
  const returnStatement = appFile.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
888
1071
  if (!returnStatement) return {
889
1072
  updated: false,
890
- filePath: appFile.getFilePath(),
1073
+ filePath: appFilePath,
891
1074
  alreadyModified: false
892
1075
  };
893
1076
  const expression = returnStatement.getExpression();
894
1077
  if (!expression) return {
895
1078
  updated: false,
896
- filePath: appFile.getFilePath(),
1079
+ filePath: appFilePath,
897
1080
  alreadyModified: false
898
1081
  };
899
1082
  const originalJsx = expression.getText();
900
- const newJsx = wrapPagesJsxContent(originalJsx, optionsText);
1083
+ const newJsx = wrapPagesJsxContent(originalJsx);
901
1084
  returnStatement.replaceWithText(`return ${newJsx}`);
902
1085
  await appFile.save();
903
1086
  return {
904
1087
  updated: true,
905
- filePath: appFile.getFilePath(),
906
- alreadyModified: false
1088
+ filePath: appFilePath,
1089
+ alreadyModified: false,
1090
+ componentFiles
907
1091
  };
908
1092
  }
909
1093
  function detectNextJsStructure(projectRoot) {
@@ -945,57 +1129,119 @@ async function updateNextLayout(options) {
945
1129
  structureType
946
1130
  };
947
1131
  }
948
- function updateGenericReactImports(layoutFile, packageName, mode) {
949
- const requiredImports = [
950
- 'ConsentManagerProvider',
951
- ...getBaseImports()
952
- ];
953
- let hasPackageImport = false;
954
- for (const importDecl of layoutFile.getImportDeclarations())if (importDecl.getModuleSpecifierValue() === packageName) {
955
- hasPackageImport = true;
956
- const namedImports = importDecl.getNamedImports().map((i)=>i.getName());
957
- const missingImports = requiredImports.filter((imp)=>!namedImports.includes(imp));
958
- if (missingImports.length > 0) importDecl.addNamedImports(missingImports);
959
- break;
960
- }
961
- if (!hasPackageImport) layoutFile.addImportDeclaration({
962
- namedImports: requiredImports,
963
- moduleSpecifier: packageName
1132
+ function react_components_generateConsentManagerTemplate(optionsText) {
1133
+ return `import type { ReactNode } from 'react';
1134
+ import {
1135
+ ConsentManagerDialog,
1136
+ ConsentManagerProvider,
1137
+ CookieBanner,
1138
+ } from '@c15t/react';
1139
+
1140
+ /**
1141
+ * Consent management wrapper for React
1142
+ *
1143
+ * This component wraps your app with consent management functionality,
1144
+ * including the cookie banner, consent dialog, and provider.
1145
+ *
1146
+ * @param props - Component properties
1147
+ * @param props.children - Child components to render within the consent manager context
1148
+ *
1149
+ * @returns The consent manager provider with banner and dialog
1150
+ *
1151
+ * @example
1152
+ * \`\`\`tsx
1153
+ * // In your App.tsx
1154
+ * import { ConsentManager } from './consent-manager';
1155
+ *
1156
+ * export default function App() {
1157
+ * return (
1158
+ * <ConsentManager>
1159
+ * <YourApp />
1160
+ * </ConsentManager>
1161
+ * );
1162
+ * }
1163
+ * \`\`\`
1164
+ */
1165
+ export function ConsentManager({ children }: { children: ReactNode }) {
1166
+ return (
1167
+ <ConsentManagerProvider
1168
+ options={${optionsText}}
1169
+ >
1170
+ <CookieBanner />
1171
+ <ConsentManagerDialog />
1172
+ {children}
1173
+ </ConsentManagerProvider>
1174
+ );
1175
+ }
1176
+ `;
1177
+ }
1178
+ function templates_layout_computeRelativeModuleSpecifier(fromFilePath, toFilePath) {
1179
+ const fromDir = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].dirname(fromFilePath);
1180
+ let relativePath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(fromDir, toFilePath);
1181
+ relativePath = relativePath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep).join('/');
1182
+ relativePath = relativePath.replace(/\.(tsx?|jsx?)$/, '');
1183
+ if (!relativePath.startsWith('.')) relativePath = `./${relativePath}`;
1184
+ return relativePath;
1185
+ }
1186
+ function templates_layout_addConsentManagerImport(layoutFile, consentManagerFilePath) {
1187
+ const layoutFilePath = layoutFile.getFilePath();
1188
+ const moduleSpecifier = templates_layout_computeRelativeModuleSpecifier(layoutFilePath, consentManagerFilePath);
1189
+ const existingImports = layoutFile.getImportDeclarations();
1190
+ const hasConsentManagerImport = existingImports.some((importDecl)=>{
1191
+ const existingSpec = importDecl.getModuleSpecifierValue();
1192
+ return existingSpec === moduleSpecifier || existingSpec.endsWith('consent-manager') || existingSpec.endsWith('consent-manager.tsx');
1193
+ });
1194
+ if (!hasConsentManagerImport) layoutFile.addImportDeclaration({
1195
+ namedImports: [
1196
+ 'ConsentManager'
1197
+ ],
1198
+ moduleSpecifier
964
1199
  });
965
- if ('custom' === mode) for (const customImport of getCustomModeImports())layoutFile.addImportDeclaration(customImport);
966
1200
  }
967
- function updateGenericReactJsx(layoutFile, mode, backendURL, useEnvFile, proxyNextjs) {
1201
+ function getSourceDirectory(layoutFilePath) {
1202
+ const normalizedPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].normalize(layoutFilePath);
1203
+ const segments = normalizedPath.split(__WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].sep);
1204
+ if (segments.includes('src')) return 'src';
1205
+ return '';
1206
+ }
1207
+ function updateGenericReactJsx(layoutFile) {
968
1208
  const functionDeclarations = layoutFile.getFunctions();
969
1209
  const variableDeclarations = layoutFile.getVariableDeclarations();
970
1210
  for (const func of functionDeclarations){
971
1211
  const returnStatement = func.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
972
- if (returnStatement) return wrapReturnStatement(returnStatement, mode, backendURL, useEnvFile, proxyNextjs);
1212
+ if (returnStatement) return wrapReturnStatementWithConsentManager(returnStatement);
973
1213
  }
974
1214
  for (const varDecl of variableDeclarations){
975
1215
  const initializer = varDecl.getInitializer();
976
1216
  if (initializer) {
977
1217
  const returnStatement = initializer.getDescendantsOfKind(__WEBPACK_EXTERNAL_MODULE_ts_morph_07c7ce60__.SyntaxKind.ReturnStatement)[0];
978
- if (returnStatement) return wrapReturnStatement(returnStatement, mode, backendURL, useEnvFile, proxyNextjs);
1218
+ if (returnStatement) return wrapReturnStatementWithConsentManager(returnStatement);
979
1219
  }
980
1220
  }
981
1221
  return false;
982
1222
  }
983
- function wrapReturnStatement(returnStatement, mode, backendURL, useEnvFile, proxyNextjs) {
1223
+ function wrapReturnStatementWithConsentManager(returnStatement) {
984
1224
  const expression = returnStatement.getExpression();
985
1225
  if (!expression) return false;
986
1226
  const originalJsx = expression.getText();
987
- const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
988
1227
  const newJsx = `(
989
- <ConsentManagerProvider options={${optionsText}}>
990
- <CookieBanner />
991
- <ConsentManagerDialog />
1228
+ <ConsentManager>
992
1229
  ${originalJsx}
993
- </ConsentManagerProvider>
1230
+ </ConsentManager>
994
1231
  )`;
995
1232
  returnStatement.replaceWithText(`return ${newJsx}`);
996
1233
  return true;
997
1234
  }
998
- async function updateGenericReactLayout({ projectRoot, mode, pkg, backendURL, useEnvFile, proxyNextjs }) {
1235
+ async function layout_createConsentManagerComponent(projectRoot, sourceDir, optionsText) {
1236
+ const targetDir = sourceDir ? __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(projectRoot, sourceDir) : projectRoot;
1237
+ const consentManagerContent = react_components_generateConsentManagerTemplate(optionsText);
1238
+ const consentManagerPath = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].join(targetDir, 'consent-manager.tsx');
1239
+ await __WEBPACK_EXTERNAL_MODULE_node_fs_promises_153e37e0__["default"].writeFile(consentManagerPath, consentManagerContent, 'utf-8');
1240
+ return {
1241
+ consentManager: consentManagerPath
1242
+ };
1243
+ }
1244
+ async function updateGenericReactLayout({ projectRoot, mode, backendURL, useEnvFile, proxyNextjs }) {
999
1245
  const layoutPatterns = [
1000
1246
  'app.tsx',
1001
1247
  'App.tsx',
@@ -1024,27 +1270,32 @@ async function updateGenericReactLayout({ projectRoot, mode, pkg, backendURL, us
1024
1270
  filePath: null,
1025
1271
  alreadyModified: false
1026
1272
  };
1273
+ const layoutFilePath = layoutFile.getFilePath();
1274
+ const sourceDir = getSourceDirectory(layoutFilePath);
1027
1275
  const existingImports = layoutFile.getImportDeclarations();
1028
- const hasPackageImport = existingImports.some((importDecl)=>importDecl.getModuleSpecifierValue() === pkg);
1029
- if (hasPackageImport) return {
1276
+ const hasConsentManagerImport = existingImports.some((importDecl)=>'./consent-manager' === importDecl.getModuleSpecifierValue() || './consent-manager.tsx' === importDecl.getModuleSpecifierValue());
1277
+ if (hasConsentManagerImport) return {
1030
1278
  updated: false,
1031
- filePath: layoutFile.getFilePath(),
1279
+ filePath: layoutFilePath,
1032
1280
  alreadyModified: true
1033
1281
  };
1034
1282
  try {
1035
- updateGenericReactImports(layoutFile, pkg, mode);
1036
- const updated = updateGenericReactJsx(layoutFile, mode, backendURL, useEnvFile, proxyNextjs);
1283
+ const optionsText = generateOptionsText(mode, backendURL, useEnvFile, proxyNextjs);
1284
+ const componentFiles = await layout_createConsentManagerComponent(projectRoot, sourceDir, optionsText);
1285
+ templates_layout_addConsentManagerImport(layoutFile, componentFiles.consentManager);
1286
+ const updated = updateGenericReactJsx(layoutFile);
1037
1287
  if (updated) {
1038
1288
  await layoutFile.save();
1039
1289
  return {
1040
1290
  updated: true,
1041
- filePath: layoutFile.getFilePath(),
1042
- alreadyModified: false
1291
+ filePath: layoutFilePath,
1292
+ alreadyModified: false,
1293
+ componentFiles
1043
1294
  };
1044
1295
  }
1045
1296
  return {
1046
1297
  updated: false,
1047
- filePath: layoutFile.getFilePath(),
1298
+ filePath: layoutFilePath,
1048
1299
  alreadyModified: false
1049
1300
  };
1050
1301
  } catch (error) {
@@ -1057,7 +1308,8 @@ async function updateReactLayout(options) {
1057
1308
  if (nextResult.structureType) return {
1058
1309
  updated: nextResult.updated,
1059
1310
  filePath: nextResult.filePath,
1060
- alreadyModified: nextResult.alreadyModified
1311
+ alreadyModified: nextResult.alreadyModified,
1312
+ componentFiles: nextResult.componentFiles
1061
1313
  };
1062
1314
  }
1063
1315
  return updateGenericReactLayout(options);
@@ -1232,7 +1484,7 @@ function addNewRewritesMethod(configObject, destination, isTemplateLiteral) {
1232
1484
  return true;
1233
1485
  }
1234
1486
  async function handleReactLayout(options) {
1235
- const { projectRoot, mode, backendURL, useEnvFile, proxyNextjs, pkg, spinner } = options;
1487
+ const { projectRoot, mode, backendURL, useEnvFile, proxyNextjs, pkg, spinner, cwd } = options;
1236
1488
  spinner.start('Updating layout file...');
1237
1489
  const layoutResult = await updateReactLayout({
1238
1490
  projectRoot,
@@ -1244,13 +1496,31 @@ async function handleReactLayout(options) {
1244
1496
  });
1245
1497
  const spinnerMessage = ()=>{
1246
1498
  if (layoutResult.alreadyModified) return {
1247
- message: 'ConsentManagerProvider is already imported. Skipped layout file update.',
1248
- type: 'info'
1249
- };
1250
- if (layoutResult.updated) return {
1251
- message: `Layout file updated: ${layoutResult.filePath}`,
1499
+ message: 'ConsentManager is already imported. Skipped layout file update.',
1252
1500
  type: 'info'
1253
1501
  };
1502
+ if (layoutResult.updated) {
1503
+ const typedResult = layoutResult;
1504
+ if (typedResult.componentFiles) {
1505
+ const relativeConsentManager = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, typedResult.componentFiles.consentManager);
1506
+ const relativeLayout = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, layoutResult.filePath || '');
1507
+ if (typedResult.componentFiles.consentManagerClient) {
1508
+ const relativeConsentManagerClient = __WEBPACK_EXTERNAL_MODULE_node_path_c5b9b54f__["default"].relative(cwd, typedResult.componentFiles.consentManagerClient);
1509
+ return {
1510
+ message: `Layout setup complete!\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManager)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManagerClient)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Updated: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeLayout)}`,
1511
+ type: 'info'
1512
+ };
1513
+ }
1514
+ return {
1515
+ message: `Layout setup complete!\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Created: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeConsentManager)}\n ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].green('✓')} Updated: ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].cyan(relativeLayout)}`,
1516
+ type: 'info'
1517
+ };
1518
+ }
1519
+ return {
1520
+ message: `Layout file updated: ${layoutResult.filePath}`,
1521
+ type: 'info'
1522
+ };
1523
+ }
1254
1524
  return {
1255
1525
  message: 'Layout file not updated.',
1256
1526
  type: 'error'
@@ -1337,7 +1607,8 @@ async function generateFiles({ context, mode, spinner, useEnvFile, proxyNextjs,
1337
1607
  useEnvFile,
1338
1608
  proxyNextjs,
1339
1609
  pkg,
1340
- spinner
1610
+ spinner,
1611
+ cwd: context.cwd
1341
1612
  });
1342
1613
  result.layoutUpdated = layoutResult.layoutUpdated;
1343
1614
  result.layoutPath = layoutResult.layoutPath;
@@ -2203,11 +2474,11 @@ async function handleGitHubStar(context) {
2203
2474
 
2204
2475
  We're building c15t as an ${__WEBPACK_EXTERNAL_MODULE_picocolors__["default"].bold('open source')} project to make consent management more accessible.
2205
2476
  If you find this useful, we'd really appreciate a GitHub star - it helps others discover the project!`, '🎉 Thanks for using c15t');
2206
- const shouldOpenGithub = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
2477
+ const shouldOpenGitHub = await __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.confirm({
2207
2478
  message: 'Would you like to star c15t on GitHub now?',
2208
2479
  initialValue: true
2209
2480
  });
2210
- if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(shouldOpenGithub)) {
2481
+ if (__WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.isCancel(shouldOpenGitHub)) {
2211
2482
  telemetry.trackEvent(TelemetryEventName.ONBOARDING_GITHUB_STAR, {
2212
2483
  action: 'cancelled'
2213
2484
  });
@@ -2217,9 +2488,9 @@ If you find this useful, we'd really appreciate a GitHub star - it helps others
2217
2488
  });
2218
2489
  }
2219
2490
  telemetry.trackEvent(TelemetryEventName.ONBOARDING_GITHUB_STAR, {
2220
- action: shouldOpenGithub ? 'opened_browser' : 'declined'
2491
+ action: shouldOpenGitHub ? 'opened_browser' : 'declined'
2221
2492
  });
2222
- if (shouldOpenGithub) try {
2493
+ if (shouldOpenGitHub) try {
2223
2494
  __WEBPACK_EXTERNAL_MODULE__clack_prompts_3cae1695__.note('Your support helps us continue improving c15t.\nThank you for being part of our community!', '⭐ Star Us on GitHub');
2224
2495
  await (0, __WEBPACK_EXTERNAL_MODULE_open__["default"])('https://github.com/c15t/c15t');
2225
2496
  logger.success('GitHub repository opened. Thank you for your support!');
@@ -2656,7 +2927,7 @@ const src_commands = [
2656
2927
  },
2657
2928
  {
2658
2929
  name: 'github',
2659
- label: 'Github',
2930
+ label: 'GitHub',
2660
2931
  hint: 'Star us on GitHub',
2661
2932
  description: 'Open our GitHub repository to give us a star.',
2662
2933
  action: async (context)=>{
@@ -1,4 +1,4 @@
1
- import { type Logger } from '@doubletie/logger';
1
+ import { type Logger } from '@c15t/logger';
2
2
  export type LogLevel = 'error' | 'warn' | 'info' | 'debug';
3
3
  export declare const validLogLevels: LogLevel[];
4
4
  export type CliLogger = Logger & CliExtensions;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAI9D,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D,eAAO,MAAM,cAAc,EAAE,QAAQ,EAAuC,CAAC;AAC7E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;AAG/C,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtD;AASD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC5B,UAAU,QAAQ,GAAG,MAAM,EAC3B,SAAS,OAAO,EAChB,OAAM,OAAO,EAAO,KAClB,MA6BF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GACtB,UAAU,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,EAClD,SAAS,OAAO,EAChB,GAAG,MAAM,OAAO,EAAE,KAChB,IAqBF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,OAAO,QAAQ,KAAG,SAiDjD,CAAC"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAKzD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAC3D,eAAO,MAAM,cAAc,EAAE,QAAQ,EAAuC,CAAC;AAC7E,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;AAG/C,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACpD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACrD,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACvD,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACtD;AASD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GAC5B,UAAU,QAAQ,GAAG,MAAM,EAC3B,SAAS,OAAO,EAChB,OAAM,OAAO,EAAO,KAClB,MA6BF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,GACtB,UAAU,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,EAClD,SAAS,OAAO,EAChB,GAAG,MAAM,OAAO,EAAE,KAChB,IAqBF,CAAC;AAIF,eAAO,MAAM,eAAe,GAAI,OAAO,QAAQ,KAAG,SAgDjD,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Logger } from '@doubletie/logger';
1
+ import type { Logger } from '@c15t/logger';
2
2
  import { PostHog } from 'posthog-node';
3
3
  export declare const TelemetryEventName: {
4
4
  readonly CLI_INVOKED: "cli.invoked";
@@ -1 +1 @@
1
- {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/utils/telemetry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAMvC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DrB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC7B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAE9D;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAqB;IAEnC;;;;OAIG;gBACS,OAAO,CAAC,EAAE,gBAAgB;IA+BtC;;;;;OAKG;IACH,UAAU,CACT,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IA4CP;;;;;;;OAOG;IACH,cAAc,CACb,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IAgDP;;;;;;OAMG;IACH,YAAY,CACX,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GAC/D,IAAI;IAqBP;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAahD;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,MAAM,IAAI,IAAI;IAOd;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAgFlB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;OAIG;IACH,SAAS,IAAI,IAAI;CAgBjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/utils/telemetry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAMvC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0DrB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAC7B,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,OAAO,kBAAkB,CAAC,CAAC;AAE9D,MAAM,WAAW,gBAAgB;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IAE9D;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,qBAAa,SAAS;IACrB,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,iBAAiB,CAA4C;IACrE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,MAAM,CAAqB;IAEnC;;;;OAIG;gBACS,OAAO,CAAC,EAAE,gBAAgB;IA+BtC;;;;;OAKG;IACH,UAAU,CACT,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IA4CP;;;;;;;OAOG;IACH,cAAc,CACb,SAAS,EAAE,kBAAkB,EAC7B,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GACpE,IAAI;IAgDP;;;;;;OAMG;IACH,YAAY,CACX,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAM,GAC/D,IAAI;IAqBP;;;;;OAKG;IACH,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;IAahD;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,MAAM,IAAI,IAAI;IAOd;;;;OAIG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IAgFlB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;;;OAIG;IACH,SAAS,IAAI,IAAI;CAgBjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c15t/cli",
3
- "version": "1.6.1",
3
+ "version": "1.7.0-canary-20251012181938",
4
4
  "description": "CLI for rapid c15t setup. Scaffold React and Next.js cookie banners and a preferences centre, generate types and config, and run migration tooling for self-hosted deployments.",
5
5
  "homepage": "https://c15t.com",
6
6
  "repository": {
@@ -21,7 +21,6 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "@clack/prompts": "^0.10.1",
24
- "@doubletie/logger": "1.0.4",
25
24
  "@mrleebo/prisma-ast": "^0.12.1",
26
25
  "@types/better-sqlite3": "^7.6.13",
27
26
  "better-sqlite3": "^11.9.1",
@@ -36,8 +35,9 @@
36
35
  "posthog-node": "^4.11.7",
37
36
  "ts-morph": "^25.0.1",
38
37
  "zod": "^3.24.2",
39
- "@c15t/backend": "1.6.0",
40
- "@c15t/react": "1.6.1"
38
+ "@c15t/backend": "1.7.0-canary-20251012181938",
39
+ "@c15t/logger": "1.0.0-canary-20251012181938",
40
+ "@c15t/react": "1.7.0-canary-20251012181938"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/figlet": "^1.7.0",