canopycms-next 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context-wrapper.d.ts +25 -14
- package/dist/context-wrapper.d.ts.map +1 -1
- package/dist/context-wrapper.js +25 -1
- package/dist/context-wrapper.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/with-canopy.d.ts +21 -1
- package/dist/with-canopy.d.ts.map +1 -1
- package/dist/with-canopy.js +52 -8
- package/dist/with-canopy.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import { type CanopyContext } from 'canopycms/server';
|
|
1
|
+
import { type CanopyContext, type CanopyBuildContext, type CanopyServices } from 'canopycms/server';
|
|
2
2
|
import type { CanopyConfig, AuthPlugin, FieldConfig } from 'canopycms';
|
|
3
|
+
import { createCanopyCatchAllHandler } from './adapter';
|
|
3
4
|
export interface NextCanopyOptions {
|
|
4
5
|
config: CanopyConfig;
|
|
5
6
|
/** Auth plugin for user authentication. Optional for static deployments (deployedAs: 'static'). */
|
|
6
7
|
authPlugin?: AuthPlugin;
|
|
7
8
|
entrySchemaRegistry: Record<string, readonly FieldConfig[]>;
|
|
8
9
|
}
|
|
10
|
+
export interface NextCanopyContextResult {
|
|
11
|
+
/** Request-scoped context. Uses headers() + React cache(). Call from server components and route handlers. */
|
|
12
|
+
getCanopy: () => Promise<CanopyContext>;
|
|
13
|
+
/**
|
|
14
|
+
* Build-time context. Uses STATIC_DEPLOY_USER (full admin, no auth), no request scope needed.
|
|
15
|
+
* Safe to call from generateStaticParams, generateMetadata, and other non-request-scoped contexts.
|
|
16
|
+
* Memoized for the process lifetime — multiple calls return the same context.
|
|
17
|
+
*
|
|
18
|
+
* Returns a narrower type than getCanopy() — only buildContentTree and listEntries are
|
|
19
|
+
* available. read/readByUrlPath are excluded because build-time code should not perform
|
|
20
|
+
* per-user content reads.
|
|
21
|
+
*
|
|
22
|
+
* **Security note:** This context bypasses all branch and path ACLs. It runs as a
|
|
23
|
+
* synthetic admin user with unrestricted read access. Only use it in build-time
|
|
24
|
+
* code paths that are not exposed to end users (e.g., static generation).
|
|
25
|
+
*/
|
|
26
|
+
getCanopyForBuild: () => Promise<CanopyBuildContext>;
|
|
27
|
+
/** API catch-all route handler */
|
|
28
|
+
handler: ReturnType<typeof createCanopyCatchAllHandler>;
|
|
29
|
+
/** Underlying services (rarely needed directly) */
|
|
30
|
+
services: CanopyServices;
|
|
31
|
+
}
|
|
9
32
|
/**
|
|
10
33
|
* Create Next.js-specific wrapper around core context.
|
|
11
34
|
* Adds React cache() for per-request memoization and API handler.
|
|
@@ -15,17 +38,5 @@ export interface NextCanopyOptions {
|
|
|
15
38
|
* it is automatically wrapped with CachingAuthPlugin + FileBasedAuthCache so that
|
|
16
39
|
* auth works without network access (Lambda in prod, local in dev). The cache is populated by the worker daemon.
|
|
17
40
|
*/
|
|
18
|
-
export declare function createNextCanopyContext(options: NextCanopyOptions): Promise<
|
|
19
|
-
getCanopy: () => Promise<CanopyContext>;
|
|
20
|
-
handler: (req: Request, ctx?: {
|
|
21
|
-
params?: Promise<{
|
|
22
|
-
canopycms?: string[];
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
}> | {
|
|
25
|
-
canopycms?: string[];
|
|
26
|
-
[key: string]: unknown;
|
|
27
|
-
};
|
|
28
|
-
}) => Promise<Response>;
|
|
29
|
-
services: import("canopycms/server").CanopyServices;
|
|
30
|
-
}>;
|
|
41
|
+
export declare function createNextCanopyContext(options: NextCanopyOptions): Promise<NextCanopyContextResult>;
|
|
31
42
|
//# sourceMappingURL=context-wrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-wrapper.d.ts","sourceRoot":"","sources":["../src/context-wrapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"context-wrapper.d.ts","sourceRoot":"","sources":["../src/context-wrapper.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EAMpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAc,WAAW,EAAE,MAAM,WAAW,CAAA;AAIlF,OAAO,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AA2BvD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAA;IACpB,mGAAmG;IACnG,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,CAAC,CAAA;CAC5D;AAED,MAAM,WAAW,uBAAuB;IACtC,8GAA8G;IAC9G,SAAS,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAA;IACvC;;;;;;;;;;;;OAYG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACpD,kCAAkC;IAClC,OAAO,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAA;IACvD,mDAAmD;IACnD,QAAQ,EAAE,cAAc,CAAA;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAwIlC"}
|
package/dist/context-wrapper.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { cache } from 'react';
|
|
3
3
|
import { headers } from 'next/headers';
|
|
4
|
-
import { createCanopyContext, createCanopyServices, operatingStrategy, loadInternalGroups, loadBranchContext, } from 'canopycms/server';
|
|
4
|
+
import { createCanopyContext, createCanopyServices, operatingStrategy, loadInternalGroups, loadBranchContext, STATIC_DEPLOY_USER, } from 'canopycms/server';
|
|
5
5
|
import { authResultToCanopyUser } from 'canopycms';
|
|
6
6
|
import { CachingAuthPlugin, FileBasedAuthCache } from 'canopycms/auth/cache';
|
|
7
7
|
import { createCanopyCatchAllHandler } from './adapter';
|
|
@@ -108,6 +108,29 @@ export async function createNextCanopyContext(options) {
|
|
|
108
108
|
const getCanopy = cache(() => {
|
|
109
109
|
return coreContext.getContext();
|
|
110
110
|
});
|
|
111
|
+
// Build-time context: uses STATIC_DEPLOY_USER, no headers() call.
|
|
112
|
+
// Safe for generateStaticParams, generateMetadata, and other non-request-scoped contexts.
|
|
113
|
+
const buildContext = createCanopyContext({
|
|
114
|
+
services,
|
|
115
|
+
extractUser: async () => STATIC_DEPLOY_USER,
|
|
116
|
+
});
|
|
117
|
+
let buildContextPromise = null;
|
|
118
|
+
const getCanopyForBuild = () => {
|
|
119
|
+
if (!buildContextPromise) {
|
|
120
|
+
buildContextPromise = buildContext
|
|
121
|
+
.getContext()
|
|
122
|
+
.then(({ buildContentTree, listEntries, services }) => ({
|
|
123
|
+
buildContentTree,
|
|
124
|
+
listEntries,
|
|
125
|
+
services,
|
|
126
|
+
}))
|
|
127
|
+
.catch((err) => {
|
|
128
|
+
buildContextPromise = null;
|
|
129
|
+
throw err;
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return buildContextPromise;
|
|
133
|
+
};
|
|
111
134
|
// Create API handler using same services
|
|
112
135
|
const handler = createCanopyCatchAllHandler({
|
|
113
136
|
...options,
|
|
@@ -116,6 +139,7 @@ export async function createNextCanopyContext(options) {
|
|
|
116
139
|
});
|
|
117
140
|
return {
|
|
118
141
|
getCanopy,
|
|
142
|
+
getCanopyForBuild,
|
|
119
143
|
handler,
|
|
120
144
|
services,
|
|
121
145
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-wrapper.js","sourceRoot":"","sources":["../src/context-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EACL,mBAAmB,
|
|
1
|
+
{"version":3,"file":"context-wrapper.js","sourceRoot":"","sources":["../src/context-wrapper.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createCanopyCatchAllHandler, wrapNextRequest, type CanopyNextOptions } from './adapter';
|
|
2
|
-
export { createNextCanopyContext, type NextCanopyOptions } from './context-wrapper';
|
|
2
|
+
export { createNextCanopyContext, type NextCanopyOptions, type NextCanopyContextResult, } from './context-wrapper';
|
|
3
3
|
export { createMockAuthPlugin, createRejectingAuthPlugin } from './test-utils';
|
|
4
4
|
export { withCanopy, type WithCanopyOptions } from './with-canopy';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEhG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,GAC7B,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAE9E,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createCanopyCatchAllHandler, wrapNextRequest } from './adapter';
|
|
2
|
-
export { createNextCanopyContext } from './context-wrapper';
|
|
2
|
+
export { createNextCanopyContext, } from './context-wrapper';
|
|
3
3
|
export { createMockAuthPlugin, createRejectingAuthPlugin } from './test-utils';
|
|
4
4
|
export { withCanopy } from './with-canopy';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAA0B,MAAM,WAAW,CAAA;AAEhG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAA0B,MAAM,WAAW,CAAA;AAEhG,OAAO,EACL,uBAAuB,GAGxB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAA;AAE9E,OAAO,EAAE,UAAU,EAA0B,MAAM,eAAe,CAAA"}
|
package/dist/with-canopy.d.ts
CHANGED
|
@@ -2,13 +2,33 @@ import type { NextConfig } from 'next';
|
|
|
2
2
|
export interface WithCanopyOptions {
|
|
3
3
|
/** Additional packages to transpile beyond the Canopy defaults. */
|
|
4
4
|
packages?: string[];
|
|
5
|
+
/**
|
|
6
|
+
* Set to `true` for static export builds to exclude CMS-only pages.
|
|
7
|
+
*
|
|
8
|
+
* When `false` (default): adds `server.ts` and `server.tsx` to `pageExtensions`,
|
|
9
|
+
* so Next.js processes `.server.ts` and `.server.tsx` files (API routes, editor page).
|
|
10
|
+
*
|
|
11
|
+
* When `true`: leaves them out, so Next.js ignores CMS-only files during static export.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* const isCmsBuild = process.env.CANOPY_BUILD === 'cms'
|
|
16
|
+
* export default withCanopy({}, { staticBuild: !isCmsBuild })
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
staticBuild?: boolean;
|
|
5
20
|
}
|
|
6
21
|
/**
|
|
7
22
|
* Wrap your Next.js config to set up module transpilation and React
|
|
8
23
|
* resolution for CanopyCMS packages.
|
|
9
24
|
*
|
|
10
25
|
* **What it does:**
|
|
11
|
-
* -
|
|
26
|
+
* - Auto-detects installed Canopy packages and adds them to `transpilePackages`
|
|
27
|
+
* (they export raw TypeScript). Only packages found in your node_modules are
|
|
28
|
+
* added, so you don't need to worry about optional packages you haven't installed.
|
|
29
|
+
* - Adds `server.ts`/`server.tsx` to `pageExtensions` for dual-build support.
|
|
30
|
+
* CMS-only files (e.g., `route.server.ts`) are included in dev/CMS builds
|
|
31
|
+
* but excluded when `staticBuild: true` is set.
|
|
12
32
|
* - Resolves React to a single copy from your project root, preventing
|
|
13
33
|
* dual-instance crashes when using `file:` symlinks for local development
|
|
14
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-canopy.d.ts","sourceRoot":"","sources":["../src/with-canopy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"with-canopy.d.ts","sourceRoot":"","sources":["../src/with-canopy.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAA;AAiCtC,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAyBD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,UAAU,CACxB,UAAU,GAAE,UAAe,EAC3B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAqEZ"}
|
package/dist/with-canopy.js
CHANGED
|
@@ -1,23 +1,40 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
/** The core package — always required when using withCanopy. */
|
|
4
|
+
const REQUIRED_PACKAGES = ['canopycms'];
|
|
3
5
|
/**
|
|
4
|
-
* Canopy packages that need transpilation
|
|
6
|
+
* Canopy packages that need transpilation when installed.
|
|
7
|
+
* Not every adopter installs all of these (e.g., only one auth plugin,
|
|
8
|
+
* CDK only for AWS deployments). Including an uninstalled package in
|
|
9
|
+
* `transpilePackages` causes Next.js build errors, so we auto-detect.
|
|
5
10
|
*/
|
|
6
|
-
const
|
|
7
|
-
'canopycms',
|
|
11
|
+
const OPTIONAL_PACKAGES = [
|
|
8
12
|
'canopycms-next',
|
|
9
13
|
'canopycms-auth-clerk',
|
|
10
14
|
'canopycms-auth-dev',
|
|
15
|
+
'canopycms-cdk',
|
|
11
16
|
];
|
|
17
|
+
/**
|
|
18
|
+
* CMS-only page extensions used by the dual-build convention.
|
|
19
|
+
* Files with these extensions (e.g., `route.server.ts`, `page.server.tsx`)
|
|
20
|
+
* are included in dev/CMS builds but excluded from static export builds.
|
|
21
|
+
*/
|
|
22
|
+
const CMS_PAGE_EXTENSIONS = ['server.ts', 'server.tsx'];
|
|
23
|
+
/**
|
|
24
|
+
* Next.js default pageExtensions. Not exported as a public API by Next.js
|
|
25
|
+
* (only available via internal `next/dist/server/config-shared`), so we
|
|
26
|
+
* mirror them here. Must be kept in sync manually if Next.js changes defaults.
|
|
27
|
+
* As of Next.js 15.x these are: tsx, ts, jsx, js.
|
|
28
|
+
*/
|
|
29
|
+
const NEXTJS_DEFAULT_PAGE_EXTENSIONS = ['tsx', 'ts', 'jsx', 'js'];
|
|
12
30
|
/**
|
|
13
31
|
* Resolve React modules from the consumer's project root rather than from
|
|
14
32
|
* this package's location. This is critical when canopycms-next is installed
|
|
15
33
|
* via `file:` symlinks — without it, `require.resolve('react')` would walk
|
|
16
34
|
* up from the symlink target and find a different React copy.
|
|
17
35
|
*/
|
|
18
|
-
function resolveReactAliases() {
|
|
36
|
+
function resolveReactAliases(resolve) {
|
|
19
37
|
try {
|
|
20
|
-
const resolve = createRequire(path.join(process.cwd(), 'noop.js')).resolve;
|
|
21
38
|
// Alias to DIRECTORIES, not files. Webpack uses prefix matching, so
|
|
22
39
|
// aliasing `react` to a directory lets `react/jsx-runtime` resolve
|
|
23
40
|
// to `<dir>/jsx-runtime` naturally. Pointing to a file (index.js)
|
|
@@ -38,7 +55,12 @@ function resolveReactAliases() {
|
|
|
38
55
|
* resolution for CanopyCMS packages.
|
|
39
56
|
*
|
|
40
57
|
* **What it does:**
|
|
41
|
-
* -
|
|
58
|
+
* - Auto-detects installed Canopy packages and adds them to `transpilePackages`
|
|
59
|
+
* (they export raw TypeScript). Only packages found in your node_modules are
|
|
60
|
+
* added, so you don't need to worry about optional packages you haven't installed.
|
|
61
|
+
* - Adds `server.ts`/`server.tsx` to `pageExtensions` for dual-build support.
|
|
62
|
+
* CMS-only files (e.g., `route.server.ts`) are included in dev/CMS builds
|
|
63
|
+
* but excluded when `staticBuild: true` is set.
|
|
42
64
|
* - Resolves React to a single copy from your project root, preventing
|
|
43
65
|
* dual-instance crashes when using `file:` symlinks for local development
|
|
44
66
|
*
|
|
@@ -66,12 +88,27 @@ function resolveReactAliases() {
|
|
|
66
88
|
* ```
|
|
67
89
|
*/
|
|
68
90
|
export function withCanopy(nextConfig = {}, options = {}) {
|
|
91
|
+
const resolve = createRequire(path.join(process.cwd(), 'noop.js')).resolve;
|
|
92
|
+
const installedOptional = OPTIONAL_PACKAGES.filter((pkg) => {
|
|
93
|
+
try {
|
|
94
|
+
resolve(pkg);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
69
101
|
// Merge transpilePackages (deduped)
|
|
70
102
|
const existingPackages = nextConfig.transpilePackages ?? [];
|
|
71
103
|
const allPackages = [
|
|
72
|
-
...new Set([
|
|
104
|
+
...new Set([
|
|
105
|
+
...existingPackages,
|
|
106
|
+
...REQUIRED_PACKAGES,
|
|
107
|
+
...installedOptional,
|
|
108
|
+
...(options.packages ?? []),
|
|
109
|
+
]),
|
|
73
110
|
];
|
|
74
|
-
const reactAlias = resolveReactAliases();
|
|
111
|
+
const reactAlias = resolveReactAliases(resolve);
|
|
75
112
|
// Scope React aliases to only canopycms files using module.rules[].resolve.
|
|
76
113
|
// A global resolve.alias would also override Next.js's own internal React
|
|
77
114
|
// (bundled at next/dist/compiled/react/), breaking its devtools and internals.
|
|
@@ -100,9 +137,16 @@ export function withCanopy(nextConfig = {}, options = {}) {
|
|
|
100
137
|
// Until Turbopack supports absolute path aliases, consumers using
|
|
101
138
|
// file: symlinks must use `next dev --webpack` for local development.
|
|
102
139
|
// Turbopack works fine when canopycms is installed from npm (no symlinks).
|
|
140
|
+
// Dual-build support: include CMS-only page extensions unless this is a static build.
|
|
141
|
+
// Files like `route.server.ts` and `page.server.tsx` are only processed when
|
|
142
|
+
// CMS_PAGE_EXTENSIONS are in pageExtensions.
|
|
143
|
+
const pageExtensions = options.staticBuild
|
|
144
|
+
? nextConfig.pageExtensions // static build: don't add CMS extensions
|
|
145
|
+
: [...(nextConfig.pageExtensions ?? NEXTJS_DEFAULT_PAGE_EXTENSIONS), ...CMS_PAGE_EXTENSIONS];
|
|
103
146
|
return {
|
|
104
147
|
...nextConfig,
|
|
105
148
|
transpilePackages: allPackages,
|
|
149
|
+
...(pageExtensions ? { pageExtensions } : {}),
|
|
106
150
|
webpack,
|
|
107
151
|
};
|
|
108
152
|
}
|
package/dist/with-canopy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-canopy.js","sourceRoot":"","sources":["../src/with-canopy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B
|
|
1
|
+
{"version":3,"file":"with-canopy.js","sourceRoot":"","sources":["../src/with-canopy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canopycms-next",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.18",
|
|
4
4
|
"description": "Next.js adapter for CanopyCMS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"next": "^13.5.7 || ^14.2.25 || ^15.2.3 || ^16",
|
|
33
33
|
"react": "^18.0.0 || ^19.0.0",
|
|
34
|
-
"canopycms": "0.0.
|
|
34
|
+
"canopycms": "0.0.18"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/node": "^22.9.0",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"react": "^18.3.1",
|
|
41
41
|
"typescript": "^5.6.3",
|
|
42
42
|
"vitest": "^1.6.0",
|
|
43
|
-
"canopycms": "0.0.
|
|
43
|
+
"canopycms": "0.0.18"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsc -p tsconfig.build.json",
|