@abinnovision/payloadcms-wayfinder 1.0.0-beta.2
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/LICENSE +201 -0
- package/README.md +132 -0
- package/dist/admin/LinkLabelFeature.client.d.mts +5 -0
- package/dist/admin/LinkLabelFeature.client.mjs +35 -0
- package/dist/admin/index.d.mts +2 -0
- package/dist/admin/index.mjs +3 -0
- package/dist/config/collection-string-field.d.mts +20 -0
- package/dist/config/collection-string-field.mjs +33 -0
- package/dist/config/has-duplicates.d.mts +15 -0
- package/dist/config/has-duplicates.mjs +14 -0
- package/dist/config/index.d.mts +8 -0
- package/dist/config/index.mjs +8 -0
- package/dist/config/link-field.d.mts +35 -0
- package/dist/config/link-field.mjs +150 -0
- package/dist/config/load-mappings.d.mts +38 -0
- package/dist/config/load-mappings.mjs +60 -0
- package/dist/config/mapping-global.d.mts +34 -0
- package/dist/config/mapping-global.mjs +86 -0
- package/dist/config/plugin.d.mts +31 -0
- package/dist/config/plugin.mjs +36 -0
- package/dist/config/translations.d.mts +34 -0
- package/dist/config/translations.mjs +45 -0
- package/dist/index.d.mts +16 -0
- package/dist/index.mjs +15 -0
- package/dist/lexical/index.d.mts +52 -0
- package/dist/lexical/index.mjs +57 -0
- package/dist/montage/index.d.mts +32 -0
- package/dist/montage/index.mjs +30 -0
- package/dist/pattern/define-links.d.mts +187 -0
- package/dist/pattern/define-links.mjs +41 -0
- package/dist/pattern/define-mappings.d.mts +15 -0
- package/dist/pattern/define-mappings.mjs +14 -0
- package/dist/pattern/derive-link-label.d.mts +23 -0
- package/dist/pattern/derive-link-label.mjs +35 -0
- package/dist/pattern/index.d.mts +8 -0
- package/dist/pattern/index.mjs +8 -0
- package/dist/pattern/matcher.d.mts +26 -0
- package/dist/pattern/matcher.mjs +74 -0
- package/dist/pattern/param-query-path.d.mts +42 -0
- package/dist/pattern/param-query-path.mjs +53 -0
- package/dist/pattern/resolver.d.mts +30 -0
- package/dist/pattern/resolver.mjs +104 -0
- package/dist/pattern/types.d.mts +169 -0
- package/dist/pattern/types.mjs +11 -0
- package/dist/runtime/build-href.d.mts +39 -0
- package/dist/runtime/build-href.mjs +73 -0
- package/dist/runtime/build-path.d.mts +32 -0
- package/dist/runtime/build-path.mjs +49 -0
- package/dist/runtime/diagnostics.d.mts +35 -0
- package/dist/runtime/index.d.mts +7 -0
- package/dist/runtime/index.mjs +6 -0
- package/dist/runtime/resolve-link.d.mts +63 -0
- package/dist/runtime/resolve-link.mjs +89 -0
- package/dist/runtime/resolve-path.d.mts +54 -0
- package/dist/runtime/resolve-path.mjs +108 -0
- package/dist/runtime/resolve-relationship-slug.d.mts +33 -0
- package/dist/runtime/resolve-relationship-slug.mjs +51 -0
- package/package.json +133 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { variantsOf } from "../pattern/define-links.mjs";
|
|
2
|
+
import { buildHref } from "./build-href.mjs";
|
|
3
|
+
//#region src/runtime/resolve-link.ts
|
|
4
|
+
/** Types the package resolves without a declaration. */ const BUILTIN_VARIANTS = /* @__PURE__ */ new Set([
|
|
5
|
+
"none",
|
|
6
|
+
"reference",
|
|
7
|
+
"custom",
|
|
8
|
+
"same-page"
|
|
9
|
+
]);
|
|
10
|
+
const newTabProps = (newTab) => newTab ? {
|
|
11
|
+
target: "_blank",
|
|
12
|
+
rel: "noopener noreferrer"
|
|
13
|
+
} : {};
|
|
14
|
+
/**
|
|
15
|
+
* Turns a link field's value into an href.
|
|
16
|
+
*
|
|
17
|
+
* Internal references route through the collection mapping rather than any
|
|
18
|
+
* hardcoded prefix, so changing a collection's URL pattern in the CMS updates
|
|
19
|
+
* every link to it.
|
|
20
|
+
*
|
|
21
|
+
* Returns null rather than degrading to the site root. A link that silently
|
|
22
|
+
* points somewhere plausible is harder to find than one that renders nothing.
|
|
23
|
+
*
|
|
24
|
+
* @param args The link value, mappings, locale and any app-declared variants.
|
|
25
|
+
*/ const resolveLink = (args) => {
|
|
26
|
+
const link = args.link;
|
|
27
|
+
if (!link?.type || link.type === "none") return null;
|
|
28
|
+
const variant = variantsOf(args).find((it) => it.value === link.type);
|
|
29
|
+
if (variant?.resolve) return variant.resolve({
|
|
30
|
+
link,
|
|
31
|
+
context: args.context
|
|
32
|
+
});
|
|
33
|
+
if (link.type === "custom" && link.url) return {
|
|
34
|
+
href: link.url,
|
|
35
|
+
...newTabProps(link.newTab)
|
|
36
|
+
};
|
|
37
|
+
if (link.type === "same-page" && link.samePageIdentifier) return { href: `#${link.samePageIdentifier}` };
|
|
38
|
+
if (link.type === "reference" && link.reference) {
|
|
39
|
+
const { relationTo, value } = link.reference;
|
|
40
|
+
if (args.resolveReference) {
|
|
41
|
+
const href = args.resolveReference({
|
|
42
|
+
relationTo,
|
|
43
|
+
value,
|
|
44
|
+
locale: args.locale
|
|
45
|
+
});
|
|
46
|
+
return href ? {
|
|
47
|
+
href,
|
|
48
|
+
...newTabProps(link.newTab)
|
|
49
|
+
} : null;
|
|
50
|
+
}
|
|
51
|
+
if (typeof value === "string") {
|
|
52
|
+
args.onDiagnostic?.({
|
|
53
|
+
reason: "unpopulated-reference",
|
|
54
|
+
collection: relationTo
|
|
55
|
+
});
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const href = buildHref({
|
|
59
|
+
mappings: args.mappings,
|
|
60
|
+
collection: relationTo,
|
|
61
|
+
document: value,
|
|
62
|
+
locale: args.locale,
|
|
63
|
+
...args.formatHref ? { formatHref: args.formatHref } : {},
|
|
64
|
+
...args.identifierField ? { identifierField: args.identifierField } : {},
|
|
65
|
+
...args.onDiagnostic ? { onDiagnostic: args.onDiagnostic } : {}
|
|
66
|
+
});
|
|
67
|
+
return href ? {
|
|
68
|
+
href,
|
|
69
|
+
...newTabProps(link.newTab)
|
|
70
|
+
} : null;
|
|
71
|
+
}
|
|
72
|
+
if (!BUILTIN_VARIANTS.has(link.type) && !variant) args.onDiagnostic?.({
|
|
73
|
+
reason: "unknown-variant",
|
|
74
|
+
variant: link.type
|
|
75
|
+
});
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Whether a link would resolve to something navigable. Use it to decide
|
|
80
|
+
* whether to render a link at all, rather than emitting a dead anchor.
|
|
81
|
+
*
|
|
82
|
+
* @param args The same arguments as {@link resolveLink}, plus whether a label
|
|
83
|
+
* is required for the link to be worth rendering.
|
|
84
|
+
*/ const isAvailableLink = (args) => {
|
|
85
|
+
if (args.withLabel && !args.link?.label) return false;
|
|
86
|
+
return resolveLink(args) !== null;
|
|
87
|
+
};
|
|
88
|
+
//#endregion
|
|
89
|
+
export { isAvailableLink, resolveLink };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { PayloadCollectionMappingResolved } from "../pattern/types.mjs";
|
|
2
|
+
import { PayloadCollectionMatch } from "../pattern/matcher.mjs";
|
|
3
|
+
import { OnDiagnostic, ResolvePathDiagnosticReason } from "./diagnostics.mjs";
|
|
4
|
+
import { Payload, Where } from "payload";
|
|
5
|
+
//#region src/runtime/resolve-path.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* A fetched document. The concrete shape varies per collection and callers
|
|
8
|
+
* read it structurally, so it is an open record rather than the union of every
|
|
9
|
+
* generated collection type.
|
|
10
|
+
*/
|
|
11
|
+
type PayloadDocument = {
|
|
12
|
+
id: string | number;
|
|
13
|
+
} & Record<string, unknown>;
|
|
14
|
+
interface ResolvedPath {
|
|
15
|
+
match: PayloadCollectionMatch;
|
|
16
|
+
collection: string;
|
|
17
|
+
document: PayloadDocument;
|
|
18
|
+
}
|
|
19
|
+
/** Extra conditions to AND into the lookup. */
|
|
20
|
+
type ResolvePathWhere = Where | ((args: {
|
|
21
|
+
collection: string;
|
|
22
|
+
match: PayloadCollectionMatch;
|
|
23
|
+
draft: boolean;
|
|
24
|
+
}) => Where | undefined);
|
|
25
|
+
interface ResolvePathToDocumentArgs {
|
|
26
|
+
payload: Payload;
|
|
27
|
+
mappings: PayloadCollectionMappingResolved[];
|
|
28
|
+
path: string;
|
|
29
|
+
locale: string;
|
|
30
|
+
/** Read drafts rather than only published documents. */
|
|
31
|
+
draft?: boolean;
|
|
32
|
+
depth?: number;
|
|
33
|
+
identifierField?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Access rules, tenancy and language visibility all narrow which document
|
|
36
|
+
* a path may resolve to, and none of them belong to the package. Without
|
|
37
|
+
* this seam a project has to query twice or fork the function.
|
|
38
|
+
*/
|
|
39
|
+
where?: ResolvePathWhere;
|
|
40
|
+
onDiagnostic?: OnDiagnostic<ResolvePathDiagnosticReason>;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Finds the document a path resolves to, or null.
|
|
44
|
+
*
|
|
45
|
+
* Candidates are tried in specificity order and the first one that actually
|
|
46
|
+
* has a document wins. Without the fallback a nested page path would be
|
|
47
|
+
* claimed by a more specific pattern and 404 even though the page exists —
|
|
48
|
+
* `/legal/imprint` also fits `/:section/:slug`.
|
|
49
|
+
*
|
|
50
|
+
* @param args The Payload instance, mappings, path and locale.
|
|
51
|
+
*/
|
|
52
|
+
declare const resolvePathToDocument: (args: ResolvePathToDocumentArgs) => Promise<ResolvedPath | null>;
|
|
53
|
+
//#endregion
|
|
54
|
+
export { PayloadDocument, ResolvePathToDocumentArgs, ResolvePathWhere, ResolvedPath, resolvePathToDocument };
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { matchCollectionMappings } from "../pattern/matcher.mjs";
|
|
2
|
+
import { resolveParamQueryPath } from "../pattern/param-query-path.mjs";
|
|
3
|
+
//#region src/runtime/resolve-path.ts
|
|
4
|
+
/**
|
|
5
|
+
* Blocks nest arbitrarily deep and read their relationships directly, so the
|
|
6
|
+
* default is generous. Lower it when a project knows its own shape.
|
|
7
|
+
*/ const DEFAULT_DOCUMENT_DEPTH = 10;
|
|
8
|
+
/**
|
|
9
|
+
* Turns the matched scope parameters into query conditions.
|
|
10
|
+
*
|
|
11
|
+
* Reuses the same parameter resolution the mapping validator applies at save
|
|
12
|
+
* time, so a pattern that validated will query the field it promised.
|
|
13
|
+
*/ const buildScopeConditions = (args) => {
|
|
14
|
+
const config = args.payload.collections[args.collection]?.config;
|
|
15
|
+
if (!config) return [];
|
|
16
|
+
return Object.entries(args.scope).flatMap(([param, value]) => {
|
|
17
|
+
const resolved = resolveParamQueryPath({
|
|
18
|
+
config,
|
|
19
|
+
param,
|
|
20
|
+
collections: args.payload.collections,
|
|
21
|
+
mappings: args.mappings,
|
|
22
|
+
locale: args.locale,
|
|
23
|
+
...args.identifierField ? { identifierField: args.identifierField } : {}
|
|
24
|
+
});
|
|
25
|
+
return "error" in resolved ? [] : [{ [resolved.queryPath]: { equals: value } }];
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Whether a collection keeps drafts.
|
|
30
|
+
*
|
|
31
|
+
* Payload only adds `_status` to a collection that does, so both asking for a
|
|
32
|
+
* draft read and filtering on published status have to be conditional: on a
|
|
33
|
+
* collection without versions the column does not exist and the query fails
|
|
34
|
+
* outright rather than coming back empty.
|
|
35
|
+
*/ const supportsDrafts = (payload, collection) => Boolean(payload.collections[collection]?.config.versions?.drafts);
|
|
36
|
+
/**
|
|
37
|
+
* Restricts a public read to published documents.
|
|
38
|
+
*
|
|
39
|
+
* `payload.find` with `draft: false` still returns the newest version of a
|
|
40
|
+
* document, which for a drafts-enabled collection includes one that has never
|
|
41
|
+
* been published. Without this a URL becomes routable the moment someone saves
|
|
42
|
+
* a draft at it, which is the opposite of what turning drafts on is for.
|
|
43
|
+
*/ const publishedOnly = (payload, collection, draft) => !draft && supportsDrafts(payload, collection) ? [{ _status: { equals: "published" } }] : [];
|
|
44
|
+
/**
|
|
45
|
+
* Finds the document a path resolves to, or null.
|
|
46
|
+
*
|
|
47
|
+
* Candidates are tried in specificity order and the first one that actually
|
|
48
|
+
* has a document wins. Without the fallback a nested page path would be
|
|
49
|
+
* claimed by a more specific pattern and 404 even though the page exists —
|
|
50
|
+
* `/legal/imprint` also fits `/:section/:slug`.
|
|
51
|
+
*
|
|
52
|
+
* @param args The Payload instance, mappings, path and locale.
|
|
53
|
+
*/ const resolvePathToDocument = async (args) => {
|
|
54
|
+
const draft = args.draft ?? false;
|
|
55
|
+
const matches = matchCollectionMappings({
|
|
56
|
+
path: args.path,
|
|
57
|
+
locale: args.locale,
|
|
58
|
+
mappings: args.mappings
|
|
59
|
+
});
|
|
60
|
+
if (matches.length === 0) {
|
|
61
|
+
args.onDiagnostic?.({
|
|
62
|
+
reason: "no-mapping",
|
|
63
|
+
path: args.path
|
|
64
|
+
});
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
for (const match of matches) {
|
|
68
|
+
const collection = match.mapping.collection;
|
|
69
|
+
const extra = typeof args.where === "function" ? args.where({
|
|
70
|
+
collection,
|
|
71
|
+
match,
|
|
72
|
+
draft
|
|
73
|
+
}) : args.where;
|
|
74
|
+
const document = (await args.payload.find({
|
|
75
|
+
collection,
|
|
76
|
+
locale: args.locale,
|
|
77
|
+
draft: draft && supportsDrafts(args.payload, collection),
|
|
78
|
+
overrideAccess: true,
|
|
79
|
+
limit: 1,
|
|
80
|
+
depth: args.depth ?? DEFAULT_DOCUMENT_DEPTH,
|
|
81
|
+
where: { and: [
|
|
82
|
+
{ [match.identifier.field]: { equals: match.identifier.value } },
|
|
83
|
+
...buildScopeConditions({
|
|
84
|
+
payload: args.payload,
|
|
85
|
+
collection,
|
|
86
|
+
scope: match.scope,
|
|
87
|
+
mappings: args.mappings,
|
|
88
|
+
locale: args.locale,
|
|
89
|
+
...args.identifierField ? { identifierField: args.identifierField } : {}
|
|
90
|
+
}),
|
|
91
|
+
...publishedOnly(args.payload, collection, draft),
|
|
92
|
+
...extra ? [extra] : []
|
|
93
|
+
] }
|
|
94
|
+
})).docs[0];
|
|
95
|
+
if (document) return {
|
|
96
|
+
match,
|
|
97
|
+
collection,
|
|
98
|
+
document
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
args.onDiagnostic?.({
|
|
102
|
+
reason: "no-document",
|
|
103
|
+
path: args.path
|
|
104
|
+
});
|
|
105
|
+
return null;
|
|
106
|
+
};
|
|
107
|
+
//#endregion
|
|
108
|
+
export { resolvePathToDocument };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { PayloadCollectionMappingResolved } from "../pattern/types.mjs";
|
|
2
|
+
import { Payload, SanitizedCollectionConfig } from "payload";
|
|
3
|
+
//#region src/runtime/resolve-relationship-slug.d.ts
|
|
4
|
+
interface ResolveRelationshipSlugArgs {
|
|
5
|
+
payload: Payload;
|
|
6
|
+
/** The collection the pattern parameter belongs to. */
|
|
7
|
+
config: SanitizedCollectionConfig;
|
|
8
|
+
/** The pattern parameter naming the relationship. */
|
|
9
|
+
param: string;
|
|
10
|
+
/** The raw value held by the document being edited. */
|
|
11
|
+
value: unknown;
|
|
12
|
+
mappings?: PayloadCollectionMappingResolved[];
|
|
13
|
+
locale?: string;
|
|
14
|
+
identifierField?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Reads the identifier value behind a relationship parameter.
|
|
18
|
+
*
|
|
19
|
+
* The inverse of `resolveParamQueryPath`: that turns a parameter into the
|
|
20
|
+
* field a path lookup queries, this turns the same parameter into the value
|
|
21
|
+
* that field holds. The admin panel is where the two have to meet — a preview
|
|
22
|
+
* URL is built from form state, where a relationship is still a bare id and
|
|
23
|
+
* there is no populated document to read a slug off, so a URL built without
|
|
24
|
+
* this would never match back.
|
|
25
|
+
*
|
|
26
|
+
* Returns null when the value names nothing resolvable, which callers should
|
|
27
|
+
* treat as "no preview URL" rather than guessing.
|
|
28
|
+
*
|
|
29
|
+
* @param args The Payload instance, the parameter and its raw value.
|
|
30
|
+
*/
|
|
31
|
+
declare const resolveRelationshipSlug: (args: ResolveRelationshipSlugArgs) => Promise<string | null>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { ResolveRelationshipSlugArgs, resolveRelationshipSlug };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { resolversFor } from "../pattern/resolver.mjs";
|
|
2
|
+
//#region src/runtime/resolve-relationship-slug.ts
|
|
3
|
+
const identifierFor = (target, args) => {
|
|
4
|
+
const fallback = args.identifierField ?? "slug";
|
|
5
|
+
if (!args.mappings || args.locale === void 0) return fallback;
|
|
6
|
+
const mapping = args.mappings.find((it) => it.collection === target);
|
|
7
|
+
const resolvers = mapping ? resolversFor(mapping, args.locale) : void 0;
|
|
8
|
+
if (!resolvers || resolvers.specificity.hasWildcard) return fallback;
|
|
9
|
+
return resolvers.paramNames.at(-1) ?? fallback;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Reads the identifier value behind a relationship parameter.
|
|
13
|
+
*
|
|
14
|
+
* The inverse of `resolveParamQueryPath`: that turns a parameter into the
|
|
15
|
+
* field a path lookup queries, this turns the same parameter into the value
|
|
16
|
+
* that field holds. The admin panel is where the two have to meet — a preview
|
|
17
|
+
* URL is built from form state, where a relationship is still a bare id and
|
|
18
|
+
* there is no populated document to read a slug off, so a URL built without
|
|
19
|
+
* this would never match back.
|
|
20
|
+
*
|
|
21
|
+
* Returns null when the value names nothing resolvable, which callers should
|
|
22
|
+
* treat as "no preview URL" rather than guessing.
|
|
23
|
+
*
|
|
24
|
+
* @param args The Payload instance, the parameter and its raw value.
|
|
25
|
+
*/ const resolveRelationshipSlug = async (args) => {
|
|
26
|
+
const field = args.config.flattenedFields.find((it) => it.name === args.param);
|
|
27
|
+
if (field?.type !== "relationship") return typeof args.value === "string" ? args.value : null;
|
|
28
|
+
const targets = Array.isArray(field.relationTo) ? field.relationTo : [field.relationTo];
|
|
29
|
+
if (args.value && typeof args.value === "object") {
|
|
30
|
+
const identifier = identifierFor(targets[0], args);
|
|
31
|
+
const held = args.value[identifier];
|
|
32
|
+
return typeof held === "string" ? held : null;
|
|
33
|
+
}
|
|
34
|
+
if (typeof args.value !== "string") return null;
|
|
35
|
+
for (const target of targets) {
|
|
36
|
+
const identifier = identifierFor(target, args);
|
|
37
|
+
try {
|
|
38
|
+
const held = (await args.payload.findByID({
|
|
39
|
+
collection: target,
|
|
40
|
+
id: args.value,
|
|
41
|
+
depth: 0,
|
|
42
|
+
select: { [identifier]: true },
|
|
43
|
+
overrideAccess: true
|
|
44
|
+
}))[identifier];
|
|
45
|
+
if (typeof held === "string") return held;
|
|
46
|
+
} catch {}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { resolveRelationshipSlug };
|
package/package.json
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/package.json",
|
|
3
|
+
"name": "@abinnovision/payloadcms-wayfinder",
|
|
4
|
+
"version": "1.0.0-beta.2",
|
|
5
|
+
"description": "Editor-authored URL routing for Payload: collection-to-path patterns, document-to-href building, path-to-document resolution and a routing-aware link field.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"payload",
|
|
8
|
+
"payloadcms",
|
|
9
|
+
"routing",
|
|
10
|
+
"permalinks",
|
|
11
|
+
"urls",
|
|
12
|
+
"link-field"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/abinnovision/payloadcms-commons.git",
|
|
17
|
+
"directory": "packages/wayfinder"
|
|
18
|
+
},
|
|
19
|
+
"license": "Apache-2.0",
|
|
20
|
+
"author": {
|
|
21
|
+
"name": "abi group GmbH",
|
|
22
|
+
"email": "info@abigroup.io",
|
|
23
|
+
"url": "https://abigroup.io"
|
|
24
|
+
},
|
|
25
|
+
"type": "module",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.mts",
|
|
29
|
+
"default": "./dist/index.mjs"
|
|
30
|
+
},
|
|
31
|
+
"./config": {
|
|
32
|
+
"types": "./dist/config/index.d.mts",
|
|
33
|
+
"default": "./dist/config/index.mjs"
|
|
34
|
+
},
|
|
35
|
+
"./lexical": {
|
|
36
|
+
"types": "./dist/lexical/index.d.mts",
|
|
37
|
+
"default": "./dist/lexical/index.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./admin": {
|
|
40
|
+
"types": "./dist/admin/index.d.mts",
|
|
41
|
+
"default": "./dist/admin/index.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./montage": {
|
|
44
|
+
"types": "./dist/montage/index.d.mts",
|
|
45
|
+
"default": "./dist/montage/index.mjs"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"files": [
|
|
49
|
+
"dist",
|
|
50
|
+
"LICENSE",
|
|
51
|
+
"README.md"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsdown",
|
|
55
|
+
"format:check": "prettier --check 'src/**/*.{ts,tsx}' 'test/**/*.ts' '*.{json{,5},md,y{,a}ml}'",
|
|
56
|
+
"format:fix": "prettier --write 'src/**/*.{ts,tsx}' 'test/**/*.ts' '*.{json{,5},md,y{,a}ml}'",
|
|
57
|
+
"lint:check": "eslint 'src/**/*.{ts,tsx}' 'test/**/*.ts'",
|
|
58
|
+
"lint:fix": "eslint 'src/**/*.{ts,tsx}' 'test/**/*.ts' --fix",
|
|
59
|
+
"test-integration": "vitest --run --config test/integration/vitest.config.mts",
|
|
60
|
+
"test-unit": "vitest --run --coverage --config vitest.config.mts",
|
|
61
|
+
"test-unit:watch": "vitest --config vitest.config.mts",
|
|
62
|
+
"typecheck": "tsc --noEmit"
|
|
63
|
+
},
|
|
64
|
+
"lint-staged": {
|
|
65
|
+
"src/**/*.{ts,tsx}": [
|
|
66
|
+
"eslint --fix",
|
|
67
|
+
"prettier --write"
|
|
68
|
+
],
|
|
69
|
+
"*.{json{,5},md,y{,a}ml}": "prettier --write"
|
|
70
|
+
},
|
|
71
|
+
"prettier": "@abinnovision/prettier-config",
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"path-to-regexp": "^8.4.2"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@abinnovision/eslint-config-base": "^3.4.2",
|
|
77
|
+
"@abinnovision/payloadcms-montage": "0.0.0",
|
|
78
|
+
"@abinnovision/prettier-config": "^2.2.0",
|
|
79
|
+
"@arethetypeswrong/core": "^0.18.5",
|
|
80
|
+
"@lexical/react": "0.41.0",
|
|
81
|
+
"@payloadcms/db-sqlite": "3.88.0",
|
|
82
|
+
"@payloadcms/richtext-lexical": "3.88.0",
|
|
83
|
+
"@payloadcms/ui": "3.88.0",
|
|
84
|
+
"@swc/core": "^1.16.1",
|
|
85
|
+
"@types/node": "^26.3.0",
|
|
86
|
+
"@types/react": "^19.2.18",
|
|
87
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
88
|
+
"eslint": "^10.9.1",
|
|
89
|
+
"lexical": "0.41.0",
|
|
90
|
+
"payload": "3.88.0",
|
|
91
|
+
"prettier": "^3.9.5",
|
|
92
|
+
"publint": "^0.3.24",
|
|
93
|
+
"react": "^19.2.8",
|
|
94
|
+
"tsdown": "^0.22.14",
|
|
95
|
+
"typescript": "^6.0.3",
|
|
96
|
+
"unplugin-swc": "^1.5.11",
|
|
97
|
+
"vitest": "^4.1.10"
|
|
98
|
+
},
|
|
99
|
+
"peerDependencies": {
|
|
100
|
+
"@abinnovision/payloadcms-montage": ">=1.0.0-beta.1",
|
|
101
|
+
"@lexical/react": ">=0.35 <1",
|
|
102
|
+
"@payloadcms/richtext-lexical": ">=3.88.0 <4",
|
|
103
|
+
"@payloadcms/ui": ">=3.88.0 <4",
|
|
104
|
+
"lexical": ">=0.35 <1",
|
|
105
|
+
"payload": ">=3.88.0 <4",
|
|
106
|
+
"react": "^19"
|
|
107
|
+
},
|
|
108
|
+
"peerDependenciesMeta": {
|
|
109
|
+
"@abinnovision/payloadcms-montage": {
|
|
110
|
+
"optional": true
|
|
111
|
+
},
|
|
112
|
+
"@lexical/react": {
|
|
113
|
+
"optional": true
|
|
114
|
+
},
|
|
115
|
+
"@payloadcms/richtext-lexical": {
|
|
116
|
+
"optional": true
|
|
117
|
+
},
|
|
118
|
+
"@payloadcms/ui": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
121
|
+
"lexical": {
|
|
122
|
+
"optional": true
|
|
123
|
+
},
|
|
124
|
+
"react": {
|
|
125
|
+
"optional": true
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"publishConfig": {
|
|
129
|
+
"ghpr": true,
|
|
130
|
+
"npm": true,
|
|
131
|
+
"npmAccess": "public"
|
|
132
|
+
}
|
|
133
|
+
}
|