forgepress 0.0.0 → 0.0.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/dist/THIRD-PARTY-LICENSES.md +42 -0
- package/dist/_chunks/client.d.mts +2 -0
- package/dist/_chunks/config.mjs +79 -0
- package/dist/_chunks/content.mjs +733 -0
- package/dist/_chunks/error.mjs +4 -0
- package/dist/_chunks/fetch.mjs +13 -0
- package/dist/_chunks/files.mjs +32 -0
- package/dist/_chunks/libs/diff.mjs +485 -0
- package/dist/_chunks/locate.mjs +7 -0
- package/dist/_chunks/media.mjs +282 -0
- package/dist/_chunks/once.mjs +16 -0
- package/dist/_chunks/output.mjs +104 -0
- package/dist/_chunks/overlay.mjs +8 -0
- package/dist/_chunks/plugin.mjs +87 -0
- package/dist/_chunks/preview.mjs +248 -0
- package/dist/_chunks/project.d.mts +7 -0
- package/dist/_chunks/reader.mjs +19 -0
- package/dist/_chunks/reader2.mjs +797 -0
- package/dist/_chunks/references.mjs +56 -0
- package/dist/_chunks/resolve.d.mts +2 -0
- package/dist/_chunks/response.mjs +5 -0
- package/dist/_chunks/routes.mjs +9 -0
- package/dist/_chunks/serialize.mjs +82 -0
- package/dist/_chunks/settings.mjs +328 -0
- package/dist/_chunks/settings2.mjs +2 -0
- package/dist/_chunks/types.d.mts +230 -0
- package/dist/_chunks/types2.d.mts +25 -0
- package/dist/_chunks/value.mjs +139 -0
- package/dist/cli/bin.d.mts +1 -0
- package/dist/cli/bin.mjs +61 -0
- package/dist/disk/reader.d.mts +4 -0
- package/dist/disk/reader.mjs +2 -0
- package/dist/editor/index.d.mts +3 -0
- package/dist/editor/index.mjs +61951 -0
- package/dist/index.d.mts +104 -0
- package/dist/index.mjs +237 -0
- package/dist/next/preview.d.mts +1 -0
- package/dist/next/preview.mjs +3 -0
- package/dist/next/reload.d.mts +1 -0
- package/dist/next/reload.mjs +20 -0
- package/dist/next/settings.d.mts +12 -0
- package/dist/next/settings.mjs +2 -0
- package/dist/plugin/next.d.mts +11 -0
- package/dist/plugin/next.mjs +213 -0
- package/dist/plugin/nuxt.d.mts +7 -0
- package/dist/plugin/nuxt.mjs +52 -0
- package/dist/plugin/watcher.d.mts +1 -0
- package/dist/plugin/watcher.mjs +23 -0
- package/dist/preview/index.d.mts +4 -0
- package/dist/preview/index.mjs +2 -0
- package/dist/preview/react.d.mts +1 -0
- package/dist/preview/react.mjs +34 -0
- package/dist/query/fetch.d.mts +3 -0
- package/dist/query/fetch.mjs +2 -0
- package/dist/unplugin.d.mts +13 -0
- package/dist/unplugin.mjs +2 -0
- package/package.json +146 -2
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
interface FieldBase {
|
|
2
|
+
label?: string;
|
|
3
|
+
description?: string;
|
|
4
|
+
optional?: boolean;
|
|
5
|
+
translate?: boolean;
|
|
6
|
+
}
|
|
7
|
+
type FieldOptionType = 'text' | 'number' | 'boolean' | 'collection' | 'collections';
|
|
8
|
+
interface FieldOption {
|
|
9
|
+
label: string;
|
|
10
|
+
type: FieldOptionType;
|
|
11
|
+
description?: string;
|
|
12
|
+
required?: true;
|
|
13
|
+
}
|
|
14
|
+
interface FieldTypeDefinition {
|
|
15
|
+
type: string;
|
|
16
|
+
label: string;
|
|
17
|
+
options: Record<string, FieldOption>;
|
|
18
|
+
}
|
|
19
|
+
type OptionContent<TOption extends FieldOption> = TOption['type'] extends 'number' ? number : TOption['type'] extends 'boolean' ? boolean : TOption['type'] extends 'collections' ? readonly string[] : string;
|
|
20
|
+
type RequiredOptions<TOptions> = { [TKey in keyof TOptions]: TOptions[TKey] extends {
|
|
21
|
+
required: true;
|
|
22
|
+
} ? TKey : never; }[keyof TOptions];
|
|
23
|
+
type FieldOf<TDefinition extends FieldTypeDefinition> = TDefinition extends FieldTypeDefinition ? FieldBase & {
|
|
24
|
+
type: TDefinition['type'];
|
|
25
|
+
} & { [TKey in RequiredOptions<TDefinition['options']>]: OptionContent<TDefinition['options'][TKey]>; } & { [TKey in Exclude<keyof TDefinition['options'], RequiredOptions<TDefinition['options']>>]?: OptionContent<TDefinition['options'][TKey]>; } : never;
|
|
26
|
+
declare const dynamic: {
|
|
27
|
+
readonly type: "dynamic";
|
|
28
|
+
readonly label: "Dynamic";
|
|
29
|
+
readonly options: {
|
|
30
|
+
readonly collections: {
|
|
31
|
+
readonly label: "Collections";
|
|
32
|
+
readonly type: "collections";
|
|
33
|
+
readonly required: true;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
type DynamicField = FieldOf<typeof dynamic>;
|
|
38
|
+
interface DynamicBlock<TCollectionName extends string = string> {
|
|
39
|
+
collection: TCollectionName;
|
|
40
|
+
id: string;
|
|
41
|
+
}
|
|
42
|
+
type DynamicFieldContent<TField extends DynamicField> = DynamicBlock<TField['collections'][number]>[];
|
|
43
|
+
type ProviderType = 'github' | 'gitlab' | 'forgejo';
|
|
44
|
+
interface ProviderRepository {
|
|
45
|
+
owner: string;
|
|
46
|
+
name: string;
|
|
47
|
+
branch?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ProviderConfig {
|
|
50
|
+
type: ProviderType;
|
|
51
|
+
repository: ProviderRepository;
|
|
52
|
+
base?: string;
|
|
53
|
+
url?: string;
|
|
54
|
+
clientId?: string;
|
|
55
|
+
scopes?: readonly string[];
|
|
56
|
+
redirectUri?: string;
|
|
57
|
+
commitMessage?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ContentConfig {
|
|
60
|
+
indent?: number;
|
|
61
|
+
semi?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface MediaConfig {
|
|
64
|
+
dir?: string;
|
|
65
|
+
url?: string;
|
|
66
|
+
maxSize?: number;
|
|
67
|
+
}
|
|
68
|
+
export interface OutputConfig {
|
|
69
|
+
dir?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface ForgePressConfig {
|
|
72
|
+
path?: string;
|
|
73
|
+
provider?: ProviderConfig;
|
|
74
|
+
content?: ContentConfig;
|
|
75
|
+
media?: MediaConfig;
|
|
76
|
+
output?: OutputConfig;
|
|
77
|
+
}
|
|
78
|
+
interface MediaContent {
|
|
79
|
+
url: string;
|
|
80
|
+
alt?: string;
|
|
81
|
+
width?: number;
|
|
82
|
+
height?: number;
|
|
83
|
+
}
|
|
84
|
+
export type ResolvedMedia = Required<MediaConfig>;
|
|
85
|
+
declare const image: {
|
|
86
|
+
readonly type: "image";
|
|
87
|
+
readonly label: "Image";
|
|
88
|
+
readonly options: {
|
|
89
|
+
readonly multiple: {
|
|
90
|
+
readonly label: "Multiple";
|
|
91
|
+
readonly type: "boolean";
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
type ImageField = FieldOf<typeof image>;
|
|
96
|
+
type ImageFieldContent<TField extends ImageField> = TField['multiple'] extends true ? MediaContent[] : MediaContent;
|
|
97
|
+
declare const number: {
|
|
98
|
+
readonly type: "number";
|
|
99
|
+
readonly label: "Number";
|
|
100
|
+
readonly options: {
|
|
101
|
+
readonly min: {
|
|
102
|
+
readonly label: "Minimum";
|
|
103
|
+
readonly type: "number";
|
|
104
|
+
};
|
|
105
|
+
readonly max: {
|
|
106
|
+
readonly label: "Maximum";
|
|
107
|
+
readonly type: "number";
|
|
108
|
+
};
|
|
109
|
+
readonly step: {
|
|
110
|
+
readonly label: "Step";
|
|
111
|
+
readonly type: "number";
|
|
112
|
+
};
|
|
113
|
+
readonly index: {
|
|
114
|
+
readonly label: "Indexed";
|
|
115
|
+
readonly type: "boolean";
|
|
116
|
+
readonly description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry.";
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
type NumberField = FieldOf<typeof number>;
|
|
121
|
+
type NumberFieldContent = number;
|
|
122
|
+
declare const relation: {
|
|
123
|
+
readonly type: "relation";
|
|
124
|
+
readonly label: "Relation";
|
|
125
|
+
readonly options: {
|
|
126
|
+
readonly collection: {
|
|
127
|
+
readonly label: "Collection";
|
|
128
|
+
readonly type: "collection";
|
|
129
|
+
readonly required: true;
|
|
130
|
+
};
|
|
131
|
+
readonly multiple: {
|
|
132
|
+
readonly label: "Multiple";
|
|
133
|
+
readonly type: "boolean";
|
|
134
|
+
};
|
|
135
|
+
readonly index: {
|
|
136
|
+
readonly label: "Indexed";
|
|
137
|
+
readonly type: "boolean";
|
|
138
|
+
readonly description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry.";
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
};
|
|
142
|
+
type RelationField = FieldOf<typeof relation>;
|
|
143
|
+
type RelationFieldContent<TField extends RelationField> = TField['multiple'] extends true ? string[] : string;
|
|
144
|
+
declare const richtext: {
|
|
145
|
+
readonly type: "richtext";
|
|
146
|
+
readonly label: "Rich Text";
|
|
147
|
+
readonly options: {};
|
|
148
|
+
};
|
|
149
|
+
type RichTextField = FieldOf<typeof richtext>;
|
|
150
|
+
type RichTextFieldContent = string;
|
|
151
|
+
declare const text: {
|
|
152
|
+
readonly type: "text";
|
|
153
|
+
readonly label: "Text";
|
|
154
|
+
readonly options: {
|
|
155
|
+
readonly validation: {
|
|
156
|
+
readonly label: "Validation Pattern";
|
|
157
|
+
readonly type: "text";
|
|
158
|
+
};
|
|
159
|
+
readonly index: {
|
|
160
|
+
readonly label: "Indexed";
|
|
161
|
+
readonly type: "boolean";
|
|
162
|
+
readonly description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry.";
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
type TextField = FieldOf<typeof text>;
|
|
167
|
+
type TextFieldContent = string;
|
|
168
|
+
declare const video: {
|
|
169
|
+
readonly type: "video";
|
|
170
|
+
readonly label: "Video";
|
|
171
|
+
readonly options: {
|
|
172
|
+
readonly multiple: {
|
|
173
|
+
readonly label: "Multiple";
|
|
174
|
+
readonly type: "boolean";
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
type VideoField = FieldOf<typeof video>;
|
|
179
|
+
type VideoFieldContent<TField extends VideoField> = TField['multiple'] extends true ? MediaContent[] : MediaContent;
|
|
180
|
+
type Field = TextField | RichTextField | NumberField | ImageField | VideoField | RelationField | DynamicField;
|
|
181
|
+
type FieldContent<TField extends Field> = TField extends DynamicField ? DynamicFieldContent<TField> : TField extends RelationField ? RelationFieldContent<TField> : TField extends ImageField ? ImageFieldContent<TField> : TField extends VideoField ? VideoFieldContent<TField> : TField extends TextField ? TextFieldContent : TField extends NumberField ? NumberFieldContent : TField extends RichTextField ? RichTextFieldContent : never;
|
|
182
|
+
interface Collection {
|
|
183
|
+
label?: string;
|
|
184
|
+
description?: string;
|
|
185
|
+
fields: Record<string, Field>;
|
|
186
|
+
}
|
|
187
|
+
export interface ForgePressSchema {
|
|
188
|
+
collections: Record<string, Collection>;
|
|
189
|
+
locales?: readonly string[];
|
|
190
|
+
}
|
|
191
|
+
export type SchemaLocale<TSchema extends ForgePressSchema> = TSchema['locales'] extends readonly string[] ? TSchema['locales'][number] : never;
|
|
192
|
+
export interface ForgePressSchemaRegistry {}
|
|
193
|
+
export type RegisteredSchema = ForgePressSchemaRegistry extends {
|
|
194
|
+
schema: infer TSchema extends ForgePressSchema;
|
|
195
|
+
} ? TSchema : ForgePressSchema;
|
|
196
|
+
export type EntryStatus = 'published' | 'unpublished';
|
|
197
|
+
export interface EntryMeta {
|
|
198
|
+
id: string;
|
|
199
|
+
status: EntryStatus;
|
|
200
|
+
createdAt: string;
|
|
201
|
+
updatedAt: string;
|
|
202
|
+
}
|
|
203
|
+
export interface EntryRef<TCollectionName extends string = string> {
|
|
204
|
+
collection: TCollectionName;
|
|
205
|
+
id: string;
|
|
206
|
+
}
|
|
207
|
+
export interface OutputMeta {
|
|
208
|
+
id: string;
|
|
209
|
+
createdAt: string;
|
|
210
|
+
updatedAt: string;
|
|
211
|
+
}
|
|
212
|
+
export type Entry = EntryMeta & {
|
|
213
|
+
[field: string]: unknown;
|
|
214
|
+
};
|
|
215
|
+
type Translated<TSchema extends ForgePressSchema, TContent> = [SchemaLocale<TSchema>] extends [never] ? TContent : Record<SchemaLocale<TSchema>, TContent>;
|
|
216
|
+
type PartiallyTranslated<TSchema extends ForgePressSchema, TContent> = [SchemaLocale<TSchema>] extends [never] ? TContent : Partial<Record<SchemaLocale<TSchema>, TContent>>;
|
|
217
|
+
type FieldValue<TSchema extends ForgePressSchema, TField extends Field, TOptional extends boolean> = TField extends {
|
|
218
|
+
translate: true;
|
|
219
|
+
} ? TOptional extends true ? PartiallyTranslated<TSchema, FieldContent<TField>> : Translated<TSchema, FieldContent<TField>> : FieldContent<TField>;
|
|
220
|
+
type OptionalKeys<TCollection extends Collection> = { [TKey in keyof TCollection['fields']]-?: TCollection['fields'][TKey] extends {
|
|
221
|
+
optional: true;
|
|
222
|
+
} ? TKey : never; }[keyof TCollection['fields']];
|
|
223
|
+
type RequiredKeys<TCollection extends Collection> = Exclude<keyof TCollection['fields'], OptionalKeys<TCollection>>;
|
|
224
|
+
type CollectionContent<TSchema extends ForgePressSchema, TCollection extends Collection> = EntryMeta & { [TKey in RequiredKeys<TCollection>]: FieldValue<TSchema, TCollection['fields'][TKey], false>; } & { [TKey in OptionalKeys<TCollection>]?: FieldValue<TSchema, TCollection['fields'][TKey], true>; };
|
|
225
|
+
type EntryOf<TSchema extends ForgePressSchema, TCollectionName extends keyof TSchema['collections']> = CollectionContent<TSchema, TSchema['collections'][TCollectionName]>;
|
|
226
|
+
export type ForgePressEntry<TCollectionName extends keyof RegisteredSchema['collections']> = EntryOf<RegisteredSchema, TCollectionName>;
|
|
227
|
+
type OutputValue<TField extends Field> = TField extends RelationField ? TField['multiple'] extends true ? EntryRef<TField['collection']>[] : EntryRef<TField['collection']> : FieldContent<TField>;
|
|
228
|
+
type CollectionOutput<TCollection extends Collection> = OutputMeta & { [TKey in RequiredKeys<TCollection>]: OutputValue<TCollection['fields'][TKey]>; } & { [TKey in OptionalKeys<TCollection>]?: OutputValue<TCollection['fields'][TKey]>; };
|
|
229
|
+
export type OutputOf<TSchema extends ForgePressSchema, TCollectionName extends keyof TSchema['collections']> = CollectionOutput<TSchema['collections'][TCollectionName]>;
|
|
230
|
+
export type ForgePressOutput<TCollectionName extends keyof RegisteredSchema['collections']> = OutputOf<RegisteredSchema, TCollectionName>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { OutputMeta } from "./types.mjs";
|
|
2
|
+
type LinkKind = 'relation' | 'dynamic';
|
|
3
|
+
export interface OutputEntry extends OutputMeta {
|
|
4
|
+
[field: string]: unknown;
|
|
5
|
+
}
|
|
6
|
+
export interface OutputManifest {
|
|
7
|
+
indexed: string[];
|
|
8
|
+
links: Record<string, LinkKind>;
|
|
9
|
+
entries: OutputEntry[];
|
|
10
|
+
files: Record<string, string>;
|
|
11
|
+
}
|
|
12
|
+
export type OutputCollection = {
|
|
13
|
+
localized: false;
|
|
14
|
+
manifest: string;
|
|
15
|
+
} | {
|
|
16
|
+
localized: true;
|
|
17
|
+
manifests: Record<string, string>;
|
|
18
|
+
};
|
|
19
|
+
export interface OutputIndex {
|
|
20
|
+
version: number;
|
|
21
|
+
commit: string | null;
|
|
22
|
+
dev?: true;
|
|
23
|
+
locales: string[];
|
|
24
|
+
collections: Record<string, OutputCollection>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const META_KEYS = [
|
|
2
|
+
"id",
|
|
3
|
+
"status",
|
|
4
|
+
"createdAt",
|
|
5
|
+
"updatedAt"
|
|
6
|
+
];
|
|
7
|
+
const OUTPUT_META_KEYS = [
|
|
8
|
+
"id",
|
|
9
|
+
"createdAt",
|
|
10
|
+
"updatedAt"
|
|
11
|
+
];
|
|
12
|
+
const ENTRY_STATUSES = ["published", "unpublished"];
|
|
13
|
+
const dynamic = {
|
|
14
|
+
type: "dynamic",
|
|
15
|
+
label: "Dynamic",
|
|
16
|
+
options: { collections: {
|
|
17
|
+
label: "Collections",
|
|
18
|
+
type: "collections",
|
|
19
|
+
required: true
|
|
20
|
+
} }
|
|
21
|
+
};
|
|
22
|
+
const image = {
|
|
23
|
+
type: "image",
|
|
24
|
+
label: "Image",
|
|
25
|
+
options: { multiple: {
|
|
26
|
+
label: "Multiple",
|
|
27
|
+
type: "boolean"
|
|
28
|
+
} }
|
|
29
|
+
};
|
|
30
|
+
const number = {
|
|
31
|
+
type: "number",
|
|
32
|
+
label: "Number",
|
|
33
|
+
options: {
|
|
34
|
+
min: {
|
|
35
|
+
label: "Minimum",
|
|
36
|
+
type: "number"
|
|
37
|
+
},
|
|
38
|
+
max: {
|
|
39
|
+
label: "Maximum",
|
|
40
|
+
type: "number"
|
|
41
|
+
},
|
|
42
|
+
step: {
|
|
43
|
+
label: "Step",
|
|
44
|
+
type: "number"
|
|
45
|
+
},
|
|
46
|
+
index: {
|
|
47
|
+
label: "Indexed",
|
|
48
|
+
type: "boolean",
|
|
49
|
+
description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry."
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const relation = {
|
|
54
|
+
type: "relation",
|
|
55
|
+
label: "Relation",
|
|
56
|
+
options: {
|
|
57
|
+
collection: {
|
|
58
|
+
label: "Collection",
|
|
59
|
+
type: "collection",
|
|
60
|
+
required: true
|
|
61
|
+
},
|
|
62
|
+
multiple: {
|
|
63
|
+
label: "Multiple",
|
|
64
|
+
type: "boolean"
|
|
65
|
+
},
|
|
66
|
+
index: {
|
|
67
|
+
label: "Indexed",
|
|
68
|
+
type: "boolean",
|
|
69
|
+
description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const richtext = {
|
|
74
|
+
type: "richtext",
|
|
75
|
+
label: "Rich Text",
|
|
76
|
+
options: {}
|
|
77
|
+
};
|
|
78
|
+
const text = {
|
|
79
|
+
type: "text",
|
|
80
|
+
label: "Text",
|
|
81
|
+
options: {
|
|
82
|
+
validation: {
|
|
83
|
+
label: "Validation Pattern",
|
|
84
|
+
type: "text"
|
|
85
|
+
},
|
|
86
|
+
index: {
|
|
87
|
+
label: "Indexed",
|
|
88
|
+
type: "boolean",
|
|
89
|
+
description: "Listed in the collection manifest, so queries can filter and sort on it without loading every entry."
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
function compilePattern(validation) {
|
|
94
|
+
try {
|
|
95
|
+
return new RegExp(validation, "u");
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const fieldTypes = {
|
|
101
|
+
text,
|
|
102
|
+
richtext,
|
|
103
|
+
number,
|
|
104
|
+
image,
|
|
105
|
+
video: {
|
|
106
|
+
type: "video",
|
|
107
|
+
label: "Video",
|
|
108
|
+
options: { multiple: {
|
|
109
|
+
label: "Multiple",
|
|
110
|
+
type: "boolean"
|
|
111
|
+
} }
|
|
112
|
+
},
|
|
113
|
+
relation,
|
|
114
|
+
dynamic
|
|
115
|
+
};
|
|
116
|
+
const fieldTypeNames = Object.keys(fieldTypes);
|
|
117
|
+
function isTranslated(field, locales) {
|
|
118
|
+
return field.translate === true && locales.length > 0;
|
|
119
|
+
}
|
|
120
|
+
function isRecord(value) {
|
|
121
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
122
|
+
}
|
|
123
|
+
function plain(value) {
|
|
124
|
+
return JSON.parse(JSON.stringify(value));
|
|
125
|
+
}
|
|
126
|
+
function same(left, right) {
|
|
127
|
+
return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
128
|
+
}
|
|
129
|
+
function pick(record, keys) {
|
|
130
|
+
return Object.fromEntries(keys.filter((key) => record[key] !== void 0).map((key) => [key, record[key]]));
|
|
131
|
+
}
|
|
132
|
+
function defined(value) {
|
|
133
|
+
if (!value) return {};
|
|
134
|
+
return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0));
|
|
135
|
+
}
|
|
136
|
+
function quote(value) {
|
|
137
|
+
return JSON.stringify(value) ?? String(value);
|
|
138
|
+
}
|
|
139
|
+
export { ENTRY_STATUSES, META_KEYS, OUTPUT_META_KEYS, compilePattern, defined, fieldTypeNames, fieldTypes, isRecord, isTranslated, pick, plain, quote, same };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
package/dist/cli/bin.mjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { errorMessage } from "../_chunks/error.mjs";
|
|
3
|
+
import { ContentError, formatIssue, readContent } from "../_chunks/content.mjs";
|
|
4
|
+
import { buildOutput } from "../_chunks/output.mjs";
|
|
5
|
+
import { diskFiles } from "../_chunks/files.mjs";
|
|
6
|
+
import { findRoot, loadConfig, resolveConfig } from "../_chunks/config.mjs";
|
|
7
|
+
import process from "node:process";
|
|
8
|
+
import { defineCommand, runMain } from "citty";
|
|
9
|
+
var version = "0.0.2";
|
|
10
|
+
function fail(message) {
|
|
11
|
+
console.error(message);
|
|
12
|
+
process.exitCode = 1;
|
|
13
|
+
}
|
|
14
|
+
function report(issues) {
|
|
15
|
+
fail(`${issues.map(formatIssue).join("\n")}\n\n${issues.length} ${issues.length === 1 ? "problem" : "problems"} found`);
|
|
16
|
+
}
|
|
17
|
+
async function inProject(cwd, task) {
|
|
18
|
+
try {
|
|
19
|
+
await task(findRoot(cwd));
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (error instanceof ContentError) return report(error.issues);
|
|
22
|
+
fail(errorMessage(error));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function createCli(cwd) {
|
|
26
|
+
const check = defineCommand({
|
|
27
|
+
meta: {
|
|
28
|
+
name: "check",
|
|
29
|
+
description: "Check the schema and all content the way the build does"
|
|
30
|
+
},
|
|
31
|
+
run: () => inProject(cwd, async (root) => {
|
|
32
|
+
const config = resolveConfig(await loadConfig(root));
|
|
33
|
+
const { issues } = await readContent(diskFiles(root), config.paths);
|
|
34
|
+
if (issues.length > 0) return report(issues);
|
|
35
|
+
console.log("No problems found");
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
const build = defineCommand({
|
|
39
|
+
meta: {
|
|
40
|
+
name: "build",
|
|
41
|
+
description: "Check the content, then write the content output"
|
|
42
|
+
},
|
|
43
|
+
run: () => inProject(cwd, async (root) => {
|
|
44
|
+
const result = await buildOutput(root, resolveConfig(await loadConfig(root)));
|
|
45
|
+
console.log(`Wrote the content output to ${result.dir} (${result.files} ${result.files === 1 ? "file" : "files"}, ${result.commit ? `commit ${result.commit.slice(0, 7)}` : "no commit found"})`);
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
return defineCommand({
|
|
49
|
+
meta: {
|
|
50
|
+
name: "forgepress",
|
|
51
|
+
version,
|
|
52
|
+
description: "Check and build the content of a ForgePress project"
|
|
53
|
+
},
|
|
54
|
+
subCommands: {
|
|
55
|
+
check,
|
|
56
|
+
build
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
await runMain(createCli(process.cwd()));
|
|
61
|
+
export {};
|