@monkeyplus/flow 6.0.13 → 6.0.14
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/modules/content/module.mjs +12 -0
- package/modules/content/query.d.ts +1 -1
- package/modules/content/query.mjs +157 -57
- package/modules/netlify-cms/handler.d.ts +2 -0
- package/modules/netlify-cms/handler.mjs +5 -0
- package/modules/netlify-cms/module.d.ts +6 -0
- package/modules/netlify-cms/module.mjs +66 -0
- package/modules/netlify-cms/resources/admin.html +16 -0
- package/modules/netlify-cms/resources/adminV2.html +15 -0
- package/modules/netlify-cms/runtime/cms.d.ts +3 -0
- package/modules/netlify-cms/runtime/cms.mjs +3 -0
- package/modules/netlify-cms/server/api/admin.d.ts +2 -0
- package/modules/netlify-cms/server/api/admin.mjs +20 -0
- package/modules/netlify-cms/server/api/config.d.ts +2 -0
- package/modules/netlify-cms/server/api/config.mjs +72 -0
- package/modules/netlify-cms/server/api/local-fs.d.ts +2 -0
- package/modules/netlify-cms/server/api/local-fs.mjs +189 -0
- package/modules/netlify-cms/server/api/meta.d.ts +2 -0
- package/modules/netlify-cms/server/api/meta.mjs +8 -0
- package/modules/netlify-cms/server/lib/cms/handler.d.ts +2 -0
- package/modules/netlify-cms/server/lib/cms/handler.mjs +37 -0
- package/modules/netlify-cms/server/lib/cms/handlerV1.d.ts +2 -0
- package/modules/netlify-cms/server/lib/cms/handlerV1.mjs +40 -0
- package/modules/netlify-cms/server/lib/cms/helpers.d.ts +14 -0
- package/modules/netlify-cms/server/lib/cms/helpers.mjs +76 -0
- package/modules/netlify-cms/server/lib/cms/widgets.d.ts +113 -0
- package/modules/netlify-cms/server/lib/cms/widgets.mjs +168 -0
- package/modules/netlify-cms/server/lib/composables.d.ts +28 -0
- package/modules/netlify-cms/server/lib/composables.mjs +14 -0
- package/modules/netlify-cms/server/lib/entries.d.ts +25 -0
- package/modules/netlify-cms/server/lib/entries.mjs +39 -0
- package/modules/netlify-cms/server/lib/fs.d.ts +5 -0
- package/modules/netlify-cms/server/lib/fs.mjs +43 -0
- package/modules/netlify-cms/server/lib/types/collections.d.ts +16 -0
- package/modules/netlify-cms/server/lib/types/collections.mjs +0 -0
- package/modules/netlify-cms/server/lib/types/helpers.d.ts +23 -0
- package/modules/netlify-cms/server/lib/types/helpers.mjs +0 -0
- package/modules/netlify-cms/server/lib/types/index.d.ts +23 -0
- package/modules/netlify-cms/server/lib/types/index.mjs +11 -0
- package/modules/netlify-cms/server/lib/types/widgets.d.ts +39 -0
- package/modules/netlify-cms/server/lib/types/widgets.mjs +0 -0
- package/package.json +1 -1
- package/server/lib/handler.mjs +2 -2
- package/server/renderer.mjs +4 -0
- package/src/public/nitro.mjs +2 -0
- package/src/public/query-content.d.ts +8 -0
- package/src/public/query-content.mjs +103 -37
- package/src/runtime/config.d.ts +7 -0
- package/src/runtime/modules.mjs +2 -1
- package/src/runtime/nitro-plugin.d.ts +1 -0
- package/src/runtime/nitro-plugin.mjs +5 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { basename, join, resolve } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { defineEventHandler, readBody, setResponseStatus } from "nitro/h3";
|
|
5
|
+
import * as v from "valibot";
|
|
6
|
+
import { entriesFromFiles, readMediaFile } from "../lib/entries.mjs";
|
|
7
|
+
import { deleteFile, listRepoFiles, move, writeFile } from "../lib/fs.mjs";
|
|
8
|
+
const repoPath = resolve(process.cwd());
|
|
9
|
+
const paramsSchema = v.variant("action", [
|
|
10
|
+
v.object({ action: v.literal("info") }),
|
|
11
|
+
v.object({
|
|
12
|
+
action: v.literal("entriesByFolder"),
|
|
13
|
+
params: v.object({
|
|
14
|
+
folder: v.string(),
|
|
15
|
+
extension: v.string(),
|
|
16
|
+
depth: v.number()
|
|
17
|
+
})
|
|
18
|
+
}),
|
|
19
|
+
v.object({
|
|
20
|
+
action: v.literal("entriesByFiles"),
|
|
21
|
+
params: v.object({
|
|
22
|
+
files: v.array(v.object({
|
|
23
|
+
path: v.string(),
|
|
24
|
+
label: v.optional(v.string())
|
|
25
|
+
}))
|
|
26
|
+
})
|
|
27
|
+
}),
|
|
28
|
+
v.object({
|
|
29
|
+
action: v.literal("getEntry"),
|
|
30
|
+
params: v.object({
|
|
31
|
+
path: v.string()
|
|
32
|
+
})
|
|
33
|
+
}),
|
|
34
|
+
v.object({
|
|
35
|
+
action: v.literal("persistEntry"),
|
|
36
|
+
params: v.object({
|
|
37
|
+
entry: v.optional(v.object({
|
|
38
|
+
slug: v.string(),
|
|
39
|
+
path: v.string(),
|
|
40
|
+
raw: v.string(),
|
|
41
|
+
newPath: v.optional(v.string())
|
|
42
|
+
})),
|
|
43
|
+
dataFiles: v.optional(v.array(v.object({
|
|
44
|
+
slug: v.string(),
|
|
45
|
+
path: v.string(),
|
|
46
|
+
raw: v.string(),
|
|
47
|
+
newPath: v.optional(v.string())
|
|
48
|
+
}))),
|
|
49
|
+
assets: v.array(v.object({
|
|
50
|
+
path: v.string(),
|
|
51
|
+
content: v.string(),
|
|
52
|
+
encoding: v.union([v.literal("base64"), v.string()])
|
|
53
|
+
}))
|
|
54
|
+
})
|
|
55
|
+
}),
|
|
56
|
+
v.object({
|
|
57
|
+
action: v.literal("getMedia"),
|
|
58
|
+
params: v.object({
|
|
59
|
+
mediaFolder: v.string()
|
|
60
|
+
})
|
|
61
|
+
}),
|
|
62
|
+
v.object({
|
|
63
|
+
action: v.literal("getMediaFile"),
|
|
64
|
+
params: v.object({
|
|
65
|
+
path: v.string()
|
|
66
|
+
})
|
|
67
|
+
}),
|
|
68
|
+
v.object({
|
|
69
|
+
action: v.literal("persistMedia"),
|
|
70
|
+
params: v.object({
|
|
71
|
+
asset: v.object({
|
|
72
|
+
path: v.string(),
|
|
73
|
+
content: v.string(),
|
|
74
|
+
encoding: v.union([v.literal("base64"), v.string()])
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
}),
|
|
78
|
+
v.object({
|
|
79
|
+
action: v.literal("deleteFile"),
|
|
80
|
+
params: v.object({
|
|
81
|
+
path: v.string()
|
|
82
|
+
})
|
|
83
|
+
}),
|
|
84
|
+
v.object({
|
|
85
|
+
action: v.literal("deleteFiles"),
|
|
86
|
+
params: v.object({
|
|
87
|
+
paths: v.array(v.string())
|
|
88
|
+
})
|
|
89
|
+
}),
|
|
90
|
+
v.object({
|
|
91
|
+
action: v.literal("getDeployPreview"),
|
|
92
|
+
params: v.any()
|
|
93
|
+
})
|
|
94
|
+
]);
|
|
95
|
+
export default defineEventHandler(async (event) => {
|
|
96
|
+
const rawBody = await readBody(event);
|
|
97
|
+
if (!rawBody || !rawBody.action) {
|
|
98
|
+
setResponseStatus(event, 422);
|
|
99
|
+
return { error: "Unknown action" };
|
|
100
|
+
}
|
|
101
|
+
const result = v.safeParse(paramsSchema, rawBody);
|
|
102
|
+
if (!result.success) {
|
|
103
|
+
setResponseStatus(event, 422);
|
|
104
|
+
return { error: "Validation failed", details: result.issues };
|
|
105
|
+
}
|
|
106
|
+
const body = result.output;
|
|
107
|
+
try {
|
|
108
|
+
switch (body.action) {
|
|
109
|
+
case "info":
|
|
110
|
+
return {
|
|
111
|
+
repo: basename(repoPath),
|
|
112
|
+
publish_modes: ["simple"],
|
|
113
|
+
type: "local_fs"
|
|
114
|
+
};
|
|
115
|
+
case "entriesByFolder": {
|
|
116
|
+
const { folder, extension, depth } = body.params;
|
|
117
|
+
const files = await listRepoFiles(repoPath, folder, extension, depth);
|
|
118
|
+
const entries = await entriesFromFiles(
|
|
119
|
+
repoPath,
|
|
120
|
+
files.reverse().map((file) => ({ path: file }))
|
|
121
|
+
);
|
|
122
|
+
return entries;
|
|
123
|
+
}
|
|
124
|
+
case "entriesByFiles": {
|
|
125
|
+
const entries = await entriesFromFiles(repoPath, body.params.files);
|
|
126
|
+
return entries;
|
|
127
|
+
}
|
|
128
|
+
case "getEntry": {
|
|
129
|
+
const [entry] = await entriesFromFiles(repoPath, [{ path: body.params.path }]);
|
|
130
|
+
return entry;
|
|
131
|
+
}
|
|
132
|
+
case "persistEntry": {
|
|
133
|
+
const dataFiles = body.params.dataFiles || (body.params.entry ? [body.params.entry] : []);
|
|
134
|
+
await Promise.all(
|
|
135
|
+
dataFiles.map((dataFile) => writeFile(join(repoPath, dataFile.path), dataFile.raw))
|
|
136
|
+
);
|
|
137
|
+
await Promise.all(
|
|
138
|
+
body.params.assets.map((a) => writeFile(
|
|
139
|
+
join(repoPath, a.path),
|
|
140
|
+
Buffer.from(a.content, a.encoding)
|
|
141
|
+
))
|
|
142
|
+
);
|
|
143
|
+
if (dataFiles.every((dataFile) => dataFile.newPath)) {
|
|
144
|
+
await Promise.all(dataFiles.map(
|
|
145
|
+
(dataFile) => move(join(repoPath, dataFile.path), join(repoPath, dataFile.newPath))
|
|
146
|
+
));
|
|
147
|
+
}
|
|
148
|
+
return { message: "entry persisted" };
|
|
149
|
+
}
|
|
150
|
+
case "getMedia": {
|
|
151
|
+
const files = await listRepoFiles(repoPath, body.params.mediaFolder, "", 1);
|
|
152
|
+
const mediaFiles = await Promise.all(
|
|
153
|
+
files.map((file) => readMediaFile(repoPath, file))
|
|
154
|
+
);
|
|
155
|
+
return mediaFiles;
|
|
156
|
+
}
|
|
157
|
+
case "getMediaFile": {
|
|
158
|
+
const mediaFile = await readMediaFile(repoPath, body.params.path);
|
|
159
|
+
return mediaFile;
|
|
160
|
+
}
|
|
161
|
+
case "persistMedia": {
|
|
162
|
+
const asset = body.params.asset;
|
|
163
|
+
await writeFile(
|
|
164
|
+
join(repoPath, asset.path),
|
|
165
|
+
Buffer.from(asset.content, asset.encoding)
|
|
166
|
+
);
|
|
167
|
+
const file = await readMediaFile(repoPath, asset.path);
|
|
168
|
+
return file;
|
|
169
|
+
}
|
|
170
|
+
case "deleteFile": {
|
|
171
|
+
await deleteFile(repoPath, body.params.path);
|
|
172
|
+
return { message: `deleted file ${body.params.path}` };
|
|
173
|
+
}
|
|
174
|
+
case "deleteFiles": {
|
|
175
|
+
await Promise.all(
|
|
176
|
+
body.params.paths.map((filePath) => deleteFile(repoPath, filePath))
|
|
177
|
+
);
|
|
178
|
+
return { message: `deleted files ${body.params.paths.join(", ")}` };
|
|
179
|
+
}
|
|
180
|
+
case "getDeployPreview": {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
} catch (e) {
|
|
185
|
+
console.error(`Error handling ${JSON.stringify(rawBody)}: ${e.message}`);
|
|
186
|
+
setResponseStatus(event, 500);
|
|
187
|
+
return { error: "Unknown error" };
|
|
188
|
+
}
|
|
189
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineEventHandler, setResponseHeader } from "nitro/h3";
|
|
2
|
+
import { localeConfig } from "#cms-meta";
|
|
3
|
+
export default defineEventHandler(async (event) => {
|
|
4
|
+
setResponseHeader(event, "Content-Type", "application/json;charset=utf-8");
|
|
5
|
+
return {
|
|
6
|
+
locale: localeConfig
|
|
7
|
+
};
|
|
8
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import defu from "defu";
|
|
2
|
+
import { eventHandler } from "h3";
|
|
3
|
+
import yml from "js-yaml";
|
|
4
|
+
import { collections, defineCms } from "./helpers.mjs";
|
|
5
|
+
import { widgets } from "./widgets.mjs";
|
|
6
|
+
export default eventHandler(async (event) => {
|
|
7
|
+
const parts = event.req.url.split("/");
|
|
8
|
+
const { utils } = event.context.flow.app;
|
|
9
|
+
parts.pop();
|
|
10
|
+
const locale = parts.pop();
|
|
11
|
+
const options = event.context.flow.$config.netlifyCms || {};
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
config: {
|
|
14
|
+
backend: {
|
|
15
|
+
name: "git-gateway",
|
|
16
|
+
branch: "master"
|
|
17
|
+
},
|
|
18
|
+
media_folder: "public/media",
|
|
19
|
+
public_folder: "/media",
|
|
20
|
+
locale: "es",
|
|
21
|
+
local_backend: {
|
|
22
|
+
url: "/cms-api/api/v1"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
base: "/"
|
|
26
|
+
};
|
|
27
|
+
const { config, base } = defu(options || {}, defaultOptions);
|
|
28
|
+
config.media_folder = base + config.media_folder;
|
|
29
|
+
const _collections = await utils.getCmsCollections(locale, {
|
|
30
|
+
widgets,
|
|
31
|
+
collections
|
|
32
|
+
});
|
|
33
|
+
const manifest = defineCms(config, [..._collections])(`${base}content/${locale}/`, { rootDir: base });
|
|
34
|
+
const ymlConfig = yml.dump(manifest, { skipInvalid: true });
|
|
35
|
+
event.res.setHeader("Content-Type", "text/yml;charset=utf-8");
|
|
36
|
+
return ymlConfig;
|
|
37
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import defu from "defu";
|
|
2
|
+
import { eventHandler } from "h3";
|
|
3
|
+
import yml from "js-yaml";
|
|
4
|
+
import { collections, defineCms } from "./helpers.mjs";
|
|
5
|
+
import { widgets } from "./widgets.mjs";
|
|
6
|
+
export default eventHandler(async (event) => {
|
|
7
|
+
const parts = event.req.url.split("/");
|
|
8
|
+
const { utils } = event.context.flow.app;
|
|
9
|
+
parts.pop();
|
|
10
|
+
const locale = parts.pop();
|
|
11
|
+
const options = event.context.flow.$config.netlifyCms || {};
|
|
12
|
+
const defaultOptions = {
|
|
13
|
+
config: {
|
|
14
|
+
backend: {
|
|
15
|
+
name: "git-gateway",
|
|
16
|
+
branch: "master"
|
|
17
|
+
},
|
|
18
|
+
media_folder: "public/media",
|
|
19
|
+
public_folder: "/media",
|
|
20
|
+
locale: "es",
|
|
21
|
+
local_backend: {
|
|
22
|
+
url: "/cms-api/api/v1"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
base: "/"
|
|
26
|
+
};
|
|
27
|
+
const { config, base } = defu(options || {}, defaultOptions);
|
|
28
|
+
config.media_folder = base + config.media_folder;
|
|
29
|
+
const _collections = await utils.getCmsCollections(locale, {
|
|
30
|
+
widgets: {
|
|
31
|
+
...widgets,
|
|
32
|
+
image: widgets.imageV1
|
|
33
|
+
},
|
|
34
|
+
collections
|
|
35
|
+
});
|
|
36
|
+
const manifest = defineCms(config, [..._collections])(`${base}content/${locale}/`, { rootDir: base });
|
|
37
|
+
const ymlConfig = yml.dump(manifest, { skipInvalid: true });
|
|
38
|
+
event.res.setHeader("Content-Type", "text/yml;charset=utf-8");
|
|
39
|
+
return ymlConfig;
|
|
40
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CollectionFolderId, Collections, DefineCms, DefineMethod, DefineMethodExtend, Helpers, Model } from '../types';
|
|
2
|
+
export declare function mapObjIndexed<T, TResult, TKey extends string>(fn: (value: T, key: TKey, obj?: Record<TKey, T>) => TResult, obj: Record<TKey, T>): Record<TKey, TResult>;
|
|
3
|
+
export declare function collectionFile(base: Omit<Collections._Base, 'name'> & {
|
|
4
|
+
fields: Model.Fields;
|
|
5
|
+
}): DefineMethodExtend<Collections.File>;
|
|
6
|
+
declare function collectionFolder(base: CollectionFolderId): (dir: string) => DefineMethod<Collections.Folder>;
|
|
7
|
+
export declare const collections: {
|
|
8
|
+
folder: typeof collectionFolder;
|
|
9
|
+
files: Helpers.CollectionFiles;
|
|
10
|
+
file: typeof collectionFile;
|
|
11
|
+
};
|
|
12
|
+
export type AllCollections = typeof collections;
|
|
13
|
+
export declare const defineCms: DefineCms;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export function mapObjIndexed(fun, object) {
|
|
3
|
+
return Object.entries(object).reduce((acc, [key, any]) => {
|
|
4
|
+
return {
|
|
5
|
+
...acc,
|
|
6
|
+
[key]: fun(any, key)
|
|
7
|
+
};
|
|
8
|
+
}, {});
|
|
9
|
+
}
|
|
10
|
+
const collectionFiles = (base) => {
|
|
11
|
+
return (dir) => (baseDir, ctx) => {
|
|
12
|
+
const _list = mapObjIndexed((fileBase, name) => {
|
|
13
|
+
return fileBase(name);
|
|
14
|
+
}, base.files);
|
|
15
|
+
const parentDir = path.join(baseDir, dir);
|
|
16
|
+
const files = Object.values(_list).map(
|
|
17
|
+
(file) => file(parentDir, ctx)
|
|
18
|
+
);
|
|
19
|
+
const obj = {
|
|
20
|
+
name: parseName(path.join(dir)),
|
|
21
|
+
...base,
|
|
22
|
+
// description: `${localeDir.toUpperCase()}, `,
|
|
23
|
+
files
|
|
24
|
+
};
|
|
25
|
+
delete obj.id;
|
|
26
|
+
return obj;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
function parseName(name) {
|
|
30
|
+
const preName = name.replace(/\//g, "_");
|
|
31
|
+
return preName.charAt(0) === "_" ? preName.replace("_", "") : preName;
|
|
32
|
+
}
|
|
33
|
+
export function collectionFile(base) {
|
|
34
|
+
return (id) => (dirParent, ctx) => {
|
|
35
|
+
const file = path.join(dirParent, id);
|
|
36
|
+
const _fields = mapObjIndexed((buildField, id2) => {
|
|
37
|
+
return buildField(id2, ctx);
|
|
38
|
+
}, base.fields);
|
|
39
|
+
return {
|
|
40
|
+
name: parseName(path.join(path.basename(dirParent), id)),
|
|
41
|
+
...base,
|
|
42
|
+
file: `${file}.${base.extension ? base.extension : "json"}`,
|
|
43
|
+
fields: Object.values(_fields)
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function collectionFolder(base) {
|
|
48
|
+
return (dir) => (baseDir, ctx) => {
|
|
49
|
+
const _fields = mapObjIndexed((buildField, id) => {
|
|
50
|
+
return buildField(id, ctx);
|
|
51
|
+
}, base.fields);
|
|
52
|
+
const folder = path.join(baseDir, dir);
|
|
53
|
+
const obj = {
|
|
54
|
+
name: parseName(path.join(dir)),
|
|
55
|
+
...base,
|
|
56
|
+
extension: base.extension || "json",
|
|
57
|
+
folder,
|
|
58
|
+
fields: Object.values(_fields)
|
|
59
|
+
// identifier_field: '',
|
|
60
|
+
};
|
|
61
|
+
delete obj.id;
|
|
62
|
+
return obj;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export const collections = {
|
|
66
|
+
folder: collectionFolder,
|
|
67
|
+
files: collectionFiles,
|
|
68
|
+
file: collectionFile
|
|
69
|
+
};
|
|
70
|
+
export const defineCms = (options, _collections) => (dir, ctx) => {
|
|
71
|
+
const collections2 = _collections.map((c) => c(dir, ctx));
|
|
72
|
+
return {
|
|
73
|
+
...options,
|
|
74
|
+
collections: collections2
|
|
75
|
+
};
|
|
76
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import type { ContextWidget, Model, Widgets } from '../types';
|
|
2
|
+
export type BuildWidget<R> = (id: string, ctx: ContextWidget) => R;
|
|
3
|
+
export type WidgetInput<T> = Omit<T, 'widget' | 'name' | 'label'> & {
|
|
4
|
+
label?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Boolean
|
|
8
|
+
*/
|
|
9
|
+
export declare function boolean(options?: Omit<Widgets.Boolean, 'widget' | 'name'>): BuildWidget<Widgets.Boolean>;
|
|
10
|
+
/**
|
|
11
|
+
* Markdown
|
|
12
|
+
*/
|
|
13
|
+
export declare function markdown(options?: Omit<Widgets.Markdown, 'widget' | 'name'>): BuildWidget<Widgets.Markdown>;
|
|
14
|
+
/**
|
|
15
|
+
* Code
|
|
16
|
+
*/
|
|
17
|
+
export declare function code(options?: Omit<Widgets.Code, 'widget' | 'name'>): BuildWidget<Widgets.Code>;
|
|
18
|
+
/**
|
|
19
|
+
* Color
|
|
20
|
+
*/
|
|
21
|
+
export declare function color(options?: WidgetInput<Widgets.Color>): BuildWidget<Widgets.Color>;
|
|
22
|
+
/**
|
|
23
|
+
* DateTime
|
|
24
|
+
*/
|
|
25
|
+
export declare function dateTime(options?: Omit<Widgets.DateTime, 'widget' | 'name'>): BuildWidget<Widgets.DateTime>;
|
|
26
|
+
/**
|
|
27
|
+
* Hidden
|
|
28
|
+
*/
|
|
29
|
+
export declare function hidden(options?: Omit<Widgets.Hidden, 'widget' | 'name'>): BuildWidget<Widgets.Hidden>;
|
|
30
|
+
/**
|
|
31
|
+
* List
|
|
32
|
+
*/
|
|
33
|
+
export declare function list(options: Omit<Widgets.List, 'widget' | 'name' | 'fields'> & {
|
|
34
|
+
fields: Model.Fields;
|
|
35
|
+
}): BuildWidget<Widgets.List>;
|
|
36
|
+
/**
|
|
37
|
+
* Map
|
|
38
|
+
*/
|
|
39
|
+
export declare function map(options: Omit<Widgets.Map, 'widget' | 'name'>): BuildWidget<Widgets.Map>;
|
|
40
|
+
/**
|
|
41
|
+
* Number
|
|
42
|
+
*/
|
|
43
|
+
export declare function number(options: Omit<Widgets.Number, 'widget' | 'name'>): BuildWidget<Widgets.Number>;
|
|
44
|
+
/**
|
|
45
|
+
* Object
|
|
46
|
+
*/
|
|
47
|
+
export declare function object(options: Omit<Widgets.Object, 'widget' | 'name' | 'fields'> & {
|
|
48
|
+
fields: Model.Fields;
|
|
49
|
+
}): BuildWidget<Widgets.Object>;
|
|
50
|
+
/**
|
|
51
|
+
* Select
|
|
52
|
+
*/
|
|
53
|
+
export declare function select(options: Omit<Widgets.Select, 'widget' | 'name'>): BuildWidget<Widgets.Select>;
|
|
54
|
+
/**
|
|
55
|
+
* Text
|
|
56
|
+
*/
|
|
57
|
+
export declare function text(options: Omit<Widgets.Text, 'widget' | 'name'>): BuildWidget<Widgets.Text>;
|
|
58
|
+
/**
|
|
59
|
+
* String
|
|
60
|
+
*/
|
|
61
|
+
export declare function string(options?: WidgetInput<Widgets.String>): BuildWidget<Widgets.String>;
|
|
62
|
+
/**
|
|
63
|
+
* Relation
|
|
64
|
+
*/
|
|
65
|
+
export declare function relation(options: Omit<Widgets.Relation, 'widget' | 'name'>): BuildWidget<Widgets.Relation>;
|
|
66
|
+
/**
|
|
67
|
+
* File
|
|
68
|
+
*/
|
|
69
|
+
export declare function file(options?: WidgetInput<Widgets.File>): BuildWidget<Widgets.File>;
|
|
70
|
+
/**
|
|
71
|
+
* Image
|
|
72
|
+
*/
|
|
73
|
+
export declare function image(options?: WidgetInput<Widgets.Image>): BuildWidget<Widgets.Image>;
|
|
74
|
+
/**
|
|
75
|
+
* Image
|
|
76
|
+
*/
|
|
77
|
+
export declare function imageV1(options?: WidgetInput<Widgets.Image>): BuildWidget<Widgets.Object>;
|
|
78
|
+
/**
|
|
79
|
+
* Date
|
|
80
|
+
*/
|
|
81
|
+
export declare function date(options?: Omit<Widgets.Date, 'label' | 'name'>): BuildWidget<Widgets.Date>;
|
|
82
|
+
/**
|
|
83
|
+
* Custom
|
|
84
|
+
*/
|
|
85
|
+
export declare function custom(options?: Omit<Widgets.Meta, 'label' | 'name'>): BuildWidget<Widgets.Meta>;
|
|
86
|
+
/**
|
|
87
|
+
******************** Owner widgets ****************************
|
|
88
|
+
*/
|
|
89
|
+
/**
|
|
90
|
+
*****************************************
|
|
91
|
+
*/
|
|
92
|
+
export declare const widgets: {
|
|
93
|
+
string: typeof string;
|
|
94
|
+
color: typeof color;
|
|
95
|
+
number: typeof number;
|
|
96
|
+
custom: typeof custom;
|
|
97
|
+
hidden: typeof hidden;
|
|
98
|
+
file: typeof file;
|
|
99
|
+
date: typeof date;
|
|
100
|
+
dateTime: typeof dateTime;
|
|
101
|
+
code: typeof code;
|
|
102
|
+
image: typeof image;
|
|
103
|
+
markdown: typeof markdown;
|
|
104
|
+
object: typeof object;
|
|
105
|
+
boolean: typeof boolean;
|
|
106
|
+
imageV1: typeof imageV1;
|
|
107
|
+
list: typeof list;
|
|
108
|
+
text: typeof text;
|
|
109
|
+
map: typeof map;
|
|
110
|
+
select: typeof select;
|
|
111
|
+
relation: typeof relation;
|
|
112
|
+
};
|
|
113
|
+
export type AllWidgets = typeof widgets;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { mapObjIndexed } from "./helpers.mjs";
|
|
3
|
+
function returnWidget(widget, options = {}) {
|
|
4
|
+
return (name, ctx) => ({
|
|
5
|
+
name,
|
|
6
|
+
...widget,
|
|
7
|
+
label: name,
|
|
8
|
+
...options
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
export function boolean(options) {
|
|
12
|
+
return returnWidget(
|
|
13
|
+
{ widget: "boolean" },
|
|
14
|
+
options
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
export function markdown(options) {
|
|
18
|
+
return returnWidget(
|
|
19
|
+
{ widget: "markdown" },
|
|
20
|
+
options
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
export function code(options) {
|
|
24
|
+
return returnWidget({ widget: "code" }, options);
|
|
25
|
+
}
|
|
26
|
+
export function color(options) {
|
|
27
|
+
return returnWidget(
|
|
28
|
+
{ widget: "color" },
|
|
29
|
+
options
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
export function dateTime(options) {
|
|
33
|
+
return returnWidget(
|
|
34
|
+
{ widget: "datetime" },
|
|
35
|
+
options
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
export function hidden(options) {
|
|
39
|
+
return returnWidget(
|
|
40
|
+
{ widget: "hidden" },
|
|
41
|
+
options
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
export function list(options) {
|
|
45
|
+
return (id, ctx) => {
|
|
46
|
+
return object(
|
|
47
|
+
{ ...options, widget: "list", fields: options.fields }
|
|
48
|
+
)(id, ctx);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function map(options) {
|
|
52
|
+
return returnWidget({ widget: "map" }, options);
|
|
53
|
+
}
|
|
54
|
+
export function number(options) {
|
|
55
|
+
return returnWidget(
|
|
56
|
+
{ widget: "number" },
|
|
57
|
+
options
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
export function object(options) {
|
|
61
|
+
return (id, ctx) => {
|
|
62
|
+
const _fields = mapObjIndexed((buildField, id2) => {
|
|
63
|
+
return buildField(id2, ctx);
|
|
64
|
+
}, options.fields);
|
|
65
|
+
return {
|
|
66
|
+
name: id,
|
|
67
|
+
widget: "object",
|
|
68
|
+
...options,
|
|
69
|
+
fields: Object.values(_fields)
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function select(options) {
|
|
74
|
+
return returnWidget(
|
|
75
|
+
{ widget: "select" },
|
|
76
|
+
options
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
export function text(options) {
|
|
80
|
+
return returnWidget({ widget: "text" }, options);
|
|
81
|
+
}
|
|
82
|
+
export function string(options) {
|
|
83
|
+
return returnWidget(
|
|
84
|
+
{ widget: "string" },
|
|
85
|
+
options
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
export function relation(options) {
|
|
89
|
+
return returnWidget(
|
|
90
|
+
{ widget: "relation" },
|
|
91
|
+
options
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
export function file(options) {
|
|
95
|
+
return returnWidget({ widget: "file" }, options);
|
|
96
|
+
}
|
|
97
|
+
export function image(options) {
|
|
98
|
+
return (name, ctx) => {
|
|
99
|
+
if (options?.media_folder)
|
|
100
|
+
options.media_folder = join(ctx?.rootDir || "/", options.media_folder);
|
|
101
|
+
return returnWidget(
|
|
102
|
+
{ widget: "image" },
|
|
103
|
+
options
|
|
104
|
+
)(name, ctx);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function imageV1(options) {
|
|
108
|
+
return (name, ctx) => {
|
|
109
|
+
if (options?.media_folder)
|
|
110
|
+
options.media_folder = join(ctx?.rootDir || "/", options.media_folder);
|
|
111
|
+
return {
|
|
112
|
+
name,
|
|
113
|
+
widget: "object",
|
|
114
|
+
fields: [
|
|
115
|
+
returnWidget(
|
|
116
|
+
{ widget: "image" },
|
|
117
|
+
options
|
|
118
|
+
)("src", ctx),
|
|
119
|
+
returnWidget(
|
|
120
|
+
{ widget: "string" },
|
|
121
|
+
{
|
|
122
|
+
required: false
|
|
123
|
+
}
|
|
124
|
+
)("alt", {
|
|
125
|
+
...ctx
|
|
126
|
+
}),
|
|
127
|
+
returnWidget(
|
|
128
|
+
{ widget: "string" },
|
|
129
|
+
{
|
|
130
|
+
required: false
|
|
131
|
+
}
|
|
132
|
+
)("title", ctx)
|
|
133
|
+
]
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
export function date(options) {
|
|
138
|
+
return returnWidget(
|
|
139
|
+
{
|
|
140
|
+
widget: "date"
|
|
141
|
+
},
|
|
142
|
+
options
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
export function custom(options) {
|
|
146
|
+
return returnWidget({}, options);
|
|
147
|
+
}
|
|
148
|
+
export const widgets = {
|
|
149
|
+
string,
|
|
150
|
+
color,
|
|
151
|
+
number,
|
|
152
|
+
custom,
|
|
153
|
+
hidden,
|
|
154
|
+
file,
|
|
155
|
+
date,
|
|
156
|
+
dateTime,
|
|
157
|
+
code,
|
|
158
|
+
image,
|
|
159
|
+
markdown,
|
|
160
|
+
object,
|
|
161
|
+
boolean,
|
|
162
|
+
imageV1,
|
|
163
|
+
list,
|
|
164
|
+
text,
|
|
165
|
+
map,
|
|
166
|
+
select,
|
|
167
|
+
relation
|
|
168
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AllCollections } from './cms/helpers';
|
|
2
|
+
import type { AllWidgets } from './cms/widgets';
|
|
3
|
+
import type { Collections, DefineMethod } from './types';
|
|
4
|
+
type Group = 'pages' | 'posts' | 'collections' | 'settings';
|
|
5
|
+
interface Ctx {
|
|
6
|
+
widgets: AllWidgets;
|
|
7
|
+
collections: AllCollections;
|
|
8
|
+
utils: any;
|
|
9
|
+
dir: string;
|
|
10
|
+
}
|
|
11
|
+
export interface OptionsCollection {
|
|
12
|
+
dir: string;
|
|
13
|
+
group: Group;
|
|
14
|
+
injectContext?: {
|
|
15
|
+
page: string;
|
|
16
|
+
assign: string;
|
|
17
|
+
};
|
|
18
|
+
setup: (ctx: Ctx) => (localeDir: string) => DefineMethod<Collections.Files | Collections.Folder>;
|
|
19
|
+
}
|
|
20
|
+
export declare function defineCmsCollection(options: OptionsCollection): (ctx: Ctx) => (baseDir: string, ctx2: any) => {
|
|
21
|
+
group: Group;
|
|
22
|
+
folder: string;
|
|
23
|
+
fields: import("./types").Cms.Fields[];
|
|
24
|
+
} | {
|
|
25
|
+
group: Group;
|
|
26
|
+
files: Collections.File[];
|
|
27
|
+
};
|
|
28
|
+
export {};
|