@myna-sh/cli 0.1.2 → 0.1.4
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/dsl.d.ts +276 -0
- package/dist/dsl.js +189 -0
- package/dist/dsl.js.map +1 -0
- package/dist/main.js +61 -10
- package/dist/main.js.map +1 -1
- package/package.json +15 -22
package/dist/dsl.d.ts
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical schema representation (SPEC 6.2 / 7).
|
|
3
|
+
*
|
|
4
|
+
* These are the normalized, serializable shapes stored as `schema_json`. Field
|
|
5
|
+
* order is significant and preserved as an array; object *keys* are sorted only
|
|
6
|
+
* during canonical stringification for a stable hash.
|
|
7
|
+
*/
|
|
8
|
+
type FieldType = "text" | "number" | "boolean" | "date" | "datetime" | "markdown" | "json" | "asset" | "reference" | "list" | "object" | "slug";
|
|
9
|
+
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
10
|
+
[key: string]: JsonValue;
|
|
11
|
+
};
|
|
12
|
+
/** UI metadata carried on every field (non-semantic, does not affect validation). */
|
|
13
|
+
interface FieldUi {
|
|
14
|
+
widget?: string;
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
helpText?: string;
|
|
17
|
+
group?: string;
|
|
18
|
+
hidden?: boolean;
|
|
19
|
+
}
|
|
20
|
+
interface FieldBase {
|
|
21
|
+
key: string;
|
|
22
|
+
type: FieldType;
|
|
23
|
+
label: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
required: boolean;
|
|
26
|
+
ui?: FieldUi;
|
|
27
|
+
}
|
|
28
|
+
interface TextField extends FieldBase {
|
|
29
|
+
type: "text";
|
|
30
|
+
multiline: boolean;
|
|
31
|
+
minLength?: number;
|
|
32
|
+
maxLength?: number;
|
|
33
|
+
pattern?: string;
|
|
34
|
+
enum?: string[];
|
|
35
|
+
default?: string;
|
|
36
|
+
}
|
|
37
|
+
interface NumberField extends FieldBase {
|
|
38
|
+
type: "number";
|
|
39
|
+
integer: boolean;
|
|
40
|
+
min?: number;
|
|
41
|
+
max?: number;
|
|
42
|
+
default?: number;
|
|
43
|
+
}
|
|
44
|
+
interface BooleanField extends FieldBase {
|
|
45
|
+
type: "boolean";
|
|
46
|
+
default?: boolean;
|
|
47
|
+
}
|
|
48
|
+
interface DateField extends FieldBase {
|
|
49
|
+
type: "date" | "datetime";
|
|
50
|
+
min?: string;
|
|
51
|
+
max?: string;
|
|
52
|
+
default?: string;
|
|
53
|
+
}
|
|
54
|
+
interface MarkdownField extends FieldBase {
|
|
55
|
+
type: "markdown";
|
|
56
|
+
minLength?: number;
|
|
57
|
+
maxLength?: number;
|
|
58
|
+
default?: string;
|
|
59
|
+
}
|
|
60
|
+
interface JsonField extends FieldBase {
|
|
61
|
+
type: "json";
|
|
62
|
+
default?: JsonValue;
|
|
63
|
+
}
|
|
64
|
+
interface AssetField extends FieldBase {
|
|
65
|
+
type: "asset";
|
|
66
|
+
/** Allowed MIME families, e.g. `image/*`, `application/pdf`. */
|
|
67
|
+
allowed: string[];
|
|
68
|
+
multiple: boolean;
|
|
69
|
+
}
|
|
70
|
+
interface ReferenceField extends FieldBase {
|
|
71
|
+
type: "reference";
|
|
72
|
+
/** Target collection key. */
|
|
73
|
+
target: string;
|
|
74
|
+
multiple: boolean;
|
|
75
|
+
}
|
|
76
|
+
interface SlugField extends FieldBase {
|
|
77
|
+
type: "slug";
|
|
78
|
+
/** Source field key to derive the slug from. */
|
|
79
|
+
from?: string;
|
|
80
|
+
}
|
|
81
|
+
type PrimitiveItem = {
|
|
82
|
+
kind: "text";
|
|
83
|
+
minLength?: number;
|
|
84
|
+
maxLength?: number;
|
|
85
|
+
pattern?: string;
|
|
86
|
+
enum?: string[];
|
|
87
|
+
} | {
|
|
88
|
+
kind: "number";
|
|
89
|
+
integer?: boolean;
|
|
90
|
+
min?: number;
|
|
91
|
+
max?: number;
|
|
92
|
+
} | {
|
|
93
|
+
kind: "boolean";
|
|
94
|
+
} | {
|
|
95
|
+
kind: "date" | "datetime";
|
|
96
|
+
min?: string;
|
|
97
|
+
max?: string;
|
|
98
|
+
} | {
|
|
99
|
+
kind: "markdown";
|
|
100
|
+
minLength?: number;
|
|
101
|
+
maxLength?: number;
|
|
102
|
+
} | {
|
|
103
|
+
kind: "json";
|
|
104
|
+
};
|
|
105
|
+
type ListItem = PrimitiveItem | {
|
|
106
|
+
kind: "reference";
|
|
107
|
+
target: string;
|
|
108
|
+
} | {
|
|
109
|
+
kind: "asset";
|
|
110
|
+
allowed: string[];
|
|
111
|
+
} | {
|
|
112
|
+
kind: "object";
|
|
113
|
+
fields: FieldDef[];
|
|
114
|
+
};
|
|
115
|
+
interface ListField extends FieldBase {
|
|
116
|
+
type: "list";
|
|
117
|
+
item: ListItem;
|
|
118
|
+
minItems?: number;
|
|
119
|
+
maxItems?: number;
|
|
120
|
+
}
|
|
121
|
+
interface ObjectField extends FieldBase {
|
|
122
|
+
type: "object";
|
|
123
|
+
fields: FieldDef[];
|
|
124
|
+
}
|
|
125
|
+
type FieldDef = TextField | NumberField | BooleanField | DateField | MarkdownField | JsonField | AssetField | ReferenceField | SlugField | ListField | ObjectField;
|
|
126
|
+
type CollectionKind = "collection" | "singleton";
|
|
127
|
+
type Visibility = "public" | "private";
|
|
128
|
+
interface SlugConfig {
|
|
129
|
+
from: string;
|
|
130
|
+
required: boolean;
|
|
131
|
+
}
|
|
132
|
+
/** Canonical collection schema (one `collection_versions.schema_json`). */
|
|
133
|
+
interface CollectionSchema {
|
|
134
|
+
name: string;
|
|
135
|
+
label: string;
|
|
136
|
+
kind: CollectionKind;
|
|
137
|
+
visibility: Visibility;
|
|
138
|
+
titleField: string | null;
|
|
139
|
+
slug: SlugConfig | null;
|
|
140
|
+
path: string | null;
|
|
141
|
+
fields: FieldDef[];
|
|
142
|
+
}
|
|
143
|
+
/** Maximum object/list nesting depth (SPEC 6.2). */
|
|
144
|
+
declare const MAX_NESTING_DEPTH = 4;
|
|
145
|
+
|
|
146
|
+
/** A field definition before its `key` is assigned by `collection()`. */
|
|
147
|
+
type FieldInput = DistributiveOmit<FieldDef, "key">;
|
|
148
|
+
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
149
|
+
interface CommonOptions {
|
|
150
|
+
label?: string;
|
|
151
|
+
description?: string;
|
|
152
|
+
required?: boolean;
|
|
153
|
+
ui?: FieldUi;
|
|
154
|
+
}
|
|
155
|
+
interface TextOptions extends CommonOptions {
|
|
156
|
+
multiline?: boolean;
|
|
157
|
+
minLength?: number;
|
|
158
|
+
maxLength?: number;
|
|
159
|
+
pattern?: string;
|
|
160
|
+
enum?: string[];
|
|
161
|
+
default?: string;
|
|
162
|
+
}
|
|
163
|
+
interface NumberOptions extends CommonOptions {
|
|
164
|
+
integer?: boolean;
|
|
165
|
+
min?: number;
|
|
166
|
+
max?: number;
|
|
167
|
+
default?: number;
|
|
168
|
+
}
|
|
169
|
+
interface BooleanOptions extends CommonOptions {
|
|
170
|
+
default?: boolean;
|
|
171
|
+
}
|
|
172
|
+
interface DateOptions extends CommonOptions {
|
|
173
|
+
min?: string;
|
|
174
|
+
max?: string;
|
|
175
|
+
default?: string;
|
|
176
|
+
}
|
|
177
|
+
interface MarkdownOptions extends CommonOptions {
|
|
178
|
+
minLength?: number;
|
|
179
|
+
maxLength?: number;
|
|
180
|
+
default?: string;
|
|
181
|
+
}
|
|
182
|
+
interface JsonOptions extends CommonOptions {
|
|
183
|
+
default?: JsonValue;
|
|
184
|
+
}
|
|
185
|
+
interface AssetOptions extends CommonOptions {
|
|
186
|
+
allowed?: string[];
|
|
187
|
+
multiple?: boolean;
|
|
188
|
+
}
|
|
189
|
+
interface ReferenceOptions extends CommonOptions {
|
|
190
|
+
to: string;
|
|
191
|
+
multiple?: boolean;
|
|
192
|
+
}
|
|
193
|
+
interface SlugOptions extends CommonOptions {
|
|
194
|
+
from?: string;
|
|
195
|
+
}
|
|
196
|
+
interface ListOptions extends CommonOptions {
|
|
197
|
+
of: ListItem;
|
|
198
|
+
minItems?: number;
|
|
199
|
+
maxItems?: number;
|
|
200
|
+
}
|
|
201
|
+
interface ObjectOptions extends CommonOptions {
|
|
202
|
+
fields: Record<string, FieldInput>;
|
|
203
|
+
}
|
|
204
|
+
declare const field: {
|
|
205
|
+
readonly text: (o?: TextOptions) => Omit<TextField, "key">;
|
|
206
|
+
readonly number: (o?: NumberOptions) => Omit<NumberField, "key">;
|
|
207
|
+
readonly boolean: (o?: BooleanOptions) => Omit<BooleanField, "key">;
|
|
208
|
+
readonly date: (o?: DateOptions) => Omit<DateField, "key">;
|
|
209
|
+
readonly datetime: (o?: DateOptions) => Omit<DateField, "key">;
|
|
210
|
+
readonly markdown: (o?: MarkdownOptions) => Omit<MarkdownField, "key">;
|
|
211
|
+
readonly json: (o?: JsonOptions) => Omit<JsonField, "key">;
|
|
212
|
+
readonly asset: (o?: AssetOptions) => Omit<AssetField, "key">;
|
|
213
|
+
readonly reference: (o: ReferenceOptions) => Omit<ReferenceField, "key">;
|
|
214
|
+
readonly slug: (o?: SlugOptions) => Omit<SlugField, "key">;
|
|
215
|
+
readonly list: (o: ListOptions) => Omit<ListField, "key">;
|
|
216
|
+
readonly object: (o: ObjectOptions) => Omit<ObjectField, "key">;
|
|
217
|
+
};
|
|
218
|
+
/** Item builders for `field.list({ of: item.<type>() })`. */
|
|
219
|
+
declare const item: {
|
|
220
|
+
readonly text: (o?: {
|
|
221
|
+
minLength?: number;
|
|
222
|
+
maxLength?: number;
|
|
223
|
+
pattern?: string;
|
|
224
|
+
enum?: string[];
|
|
225
|
+
}) => ListItem;
|
|
226
|
+
readonly number: (o?: {
|
|
227
|
+
integer?: boolean;
|
|
228
|
+
min?: number;
|
|
229
|
+
max?: number;
|
|
230
|
+
}) => ListItem;
|
|
231
|
+
readonly boolean: () => ListItem;
|
|
232
|
+
readonly date: (o?: {
|
|
233
|
+
min?: string;
|
|
234
|
+
max?: string;
|
|
235
|
+
}) => ListItem;
|
|
236
|
+
readonly datetime: (o?: {
|
|
237
|
+
min?: string;
|
|
238
|
+
max?: string;
|
|
239
|
+
}) => ListItem;
|
|
240
|
+
readonly markdown: (o?: {
|
|
241
|
+
minLength?: number;
|
|
242
|
+
maxLength?: number;
|
|
243
|
+
}) => ListItem;
|
|
244
|
+
readonly json: () => ListItem;
|
|
245
|
+
readonly reference: (o: {
|
|
246
|
+
to: string;
|
|
247
|
+
}) => ListItem;
|
|
248
|
+
readonly asset: (o?: {
|
|
249
|
+
allowed?: string[];
|
|
250
|
+
}) => ListItem;
|
|
251
|
+
readonly object: (o: {
|
|
252
|
+
fields: Record<string, FieldInput>;
|
|
253
|
+
}) => ListItem;
|
|
254
|
+
};
|
|
255
|
+
/** Turn a `{ key: FieldInput }` map into an ordered array of `FieldDef`. */
|
|
256
|
+
declare function assignKeys(fields: Record<string, FieldInput>): FieldDef[];
|
|
257
|
+
|
|
258
|
+
interface CollectionInput {
|
|
259
|
+
/** Immutable collection key, e.g. `posts`. */
|
|
260
|
+
name: string;
|
|
261
|
+
label?: string;
|
|
262
|
+
kind?: CollectionKind;
|
|
263
|
+
/** Visibility defaults to `private` and must be explicitly declared `public`. */
|
|
264
|
+
visibility?: Visibility;
|
|
265
|
+
titleField?: string;
|
|
266
|
+
/** Path template such as `/blog/{slug}`. */
|
|
267
|
+
path?: string;
|
|
268
|
+
fields: Record<string, FieldInput>;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Author a collection schema. Returns the canonical `CollectionSchema` with an
|
|
272
|
+
* ordered fields array. Defaults: `kind=collection`, `visibility=private`.
|
|
273
|
+
*/
|
|
274
|
+
declare function collection(input: CollectionInput): CollectionSchema;
|
|
275
|
+
|
|
276
|
+
export { type AssetField, type AssetOptions, type BooleanField, type BooleanOptions, type CollectionInput, type CollectionKind, type CollectionSchema, type DateField, type DateOptions, type FieldDef, type FieldInput, type FieldType, type FieldUi, type JsonField, type JsonOptions, type JsonValue, type ListField, type ListItem, type ListOptions, MAX_NESTING_DEPTH, type MarkdownField, type MarkdownOptions, type NumberField, type NumberOptions, type ObjectField, type ObjectOptions, type PrimitiveItem, type ReferenceField, type ReferenceOptions, type SlugConfig, type SlugField, type SlugOptions, type TextField, type TextOptions, type Visibility, assignKeys, collection, field, item };
|
package/dist/dsl.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// ../schema/src/types.ts
|
|
2
|
+
var MAX_NESTING_DEPTH = 4;
|
|
3
|
+
|
|
4
|
+
// ../schema/src/fields.ts
|
|
5
|
+
function common(o) {
|
|
6
|
+
const base = {
|
|
7
|
+
required: o.required ?? false
|
|
8
|
+
};
|
|
9
|
+
if (o.label !== void 0) base.label = o.label;
|
|
10
|
+
if (o.description !== void 0) base.description = o.description;
|
|
11
|
+
if (o.ui !== void 0) base.ui = o.ui;
|
|
12
|
+
return base;
|
|
13
|
+
}
|
|
14
|
+
function defined(obj) {
|
|
15
|
+
for (const key of Object.keys(obj)) {
|
|
16
|
+
if (obj[key] === void 0) delete obj[key];
|
|
17
|
+
}
|
|
18
|
+
return obj;
|
|
19
|
+
}
|
|
20
|
+
var field = {
|
|
21
|
+
text(o = {}) {
|
|
22
|
+
return defined({
|
|
23
|
+
type: "text",
|
|
24
|
+
...common(o),
|
|
25
|
+
multiline: o.multiline ?? false,
|
|
26
|
+
minLength: o.minLength,
|
|
27
|
+
maxLength: o.maxLength,
|
|
28
|
+
pattern: o.pattern,
|
|
29
|
+
enum: o.enum,
|
|
30
|
+
default: o.default
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
number(o = {}) {
|
|
34
|
+
return defined({
|
|
35
|
+
type: "number",
|
|
36
|
+
...common(o),
|
|
37
|
+
integer: o.integer ?? false,
|
|
38
|
+
min: o.min,
|
|
39
|
+
max: o.max,
|
|
40
|
+
default: o.default
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
boolean(o = {}) {
|
|
44
|
+
return defined({
|
|
45
|
+
type: "boolean",
|
|
46
|
+
...common(o),
|
|
47
|
+
default: o.default
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
date(o = {}) {
|
|
51
|
+
return defined({
|
|
52
|
+
type: "date",
|
|
53
|
+
...common(o),
|
|
54
|
+
min: o.min,
|
|
55
|
+
max: o.max,
|
|
56
|
+
default: o.default
|
|
57
|
+
});
|
|
58
|
+
},
|
|
59
|
+
datetime(o = {}) {
|
|
60
|
+
return defined({
|
|
61
|
+
type: "datetime",
|
|
62
|
+
...common(o),
|
|
63
|
+
min: o.min,
|
|
64
|
+
max: o.max,
|
|
65
|
+
default: o.default
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
markdown(o = {}) {
|
|
69
|
+
return defined({
|
|
70
|
+
type: "markdown",
|
|
71
|
+
...common(o),
|
|
72
|
+
minLength: o.minLength,
|
|
73
|
+
maxLength: o.maxLength,
|
|
74
|
+
default: o.default
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
json(o = {}) {
|
|
78
|
+
return defined({
|
|
79
|
+
type: "json",
|
|
80
|
+
...common(o),
|
|
81
|
+
default: o.default
|
|
82
|
+
});
|
|
83
|
+
},
|
|
84
|
+
asset(o = {}) {
|
|
85
|
+
return defined({
|
|
86
|
+
type: "asset",
|
|
87
|
+
...common(o),
|
|
88
|
+
allowed: o.allowed ?? ["*/*"],
|
|
89
|
+
multiple: o.multiple ?? false
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
reference(o) {
|
|
93
|
+
return defined({
|
|
94
|
+
type: "reference",
|
|
95
|
+
...common(o),
|
|
96
|
+
target: o.to,
|
|
97
|
+
multiple: o.multiple ?? false
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
slug(o = {}) {
|
|
101
|
+
return defined({
|
|
102
|
+
type: "slug",
|
|
103
|
+
...common(o),
|
|
104
|
+
from: o.from
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
list(o) {
|
|
108
|
+
return defined({
|
|
109
|
+
type: "list",
|
|
110
|
+
...common(o),
|
|
111
|
+
item: o.of,
|
|
112
|
+
minItems: o.minItems,
|
|
113
|
+
maxItems: o.maxItems
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
object(o) {
|
|
117
|
+
return defined({
|
|
118
|
+
type: "object",
|
|
119
|
+
...common(o),
|
|
120
|
+
fields: assignKeys(o.fields)
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
var item = {
|
|
125
|
+
text(o = {}) {
|
|
126
|
+
return defined({ kind: "text", ...o });
|
|
127
|
+
},
|
|
128
|
+
number(o = {}) {
|
|
129
|
+
return defined({ kind: "number", ...o });
|
|
130
|
+
},
|
|
131
|
+
boolean() {
|
|
132
|
+
return { kind: "boolean" };
|
|
133
|
+
},
|
|
134
|
+
date(o = {}) {
|
|
135
|
+
return defined({ kind: "date", ...o });
|
|
136
|
+
},
|
|
137
|
+
datetime(o = {}) {
|
|
138
|
+
return defined({ kind: "datetime", ...o });
|
|
139
|
+
},
|
|
140
|
+
markdown(o = {}) {
|
|
141
|
+
return defined({ kind: "markdown", ...o });
|
|
142
|
+
},
|
|
143
|
+
json() {
|
|
144
|
+
return { kind: "json" };
|
|
145
|
+
},
|
|
146
|
+
reference(o) {
|
|
147
|
+
return { kind: "reference", target: o.to };
|
|
148
|
+
},
|
|
149
|
+
asset(o = {}) {
|
|
150
|
+
return { kind: "asset", allowed: o.allowed ?? ["*/*"] };
|
|
151
|
+
},
|
|
152
|
+
object(o) {
|
|
153
|
+
return { kind: "object", fields: assignKeys(o.fields) };
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
function assignKeys(fields) {
|
|
157
|
+
return Object.entries(fields).map(([key, def]) => ({ key, ...def }));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ../schema/src/collection.ts
|
|
161
|
+
function collection(input) {
|
|
162
|
+
const fields = assignKeys(input.fields);
|
|
163
|
+
const slugField = fields.find((f) => f.type === "slug");
|
|
164
|
+
let slug = null;
|
|
165
|
+
if (slugField && slugField.type === "slug") {
|
|
166
|
+
slug = {
|
|
167
|
+
from: slugField.from ?? input.titleField ?? slugField.key,
|
|
168
|
+
required: slugField.required
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
name: input.name,
|
|
173
|
+
label: input.label ?? input.name,
|
|
174
|
+
kind: input.kind ?? "collection",
|
|
175
|
+
visibility: input.visibility ?? "private",
|
|
176
|
+
titleField: input.titleField ?? null,
|
|
177
|
+
slug,
|
|
178
|
+
path: input.path ?? null,
|
|
179
|
+
fields
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export {
|
|
183
|
+
MAX_NESTING_DEPTH,
|
|
184
|
+
assignKeys,
|
|
185
|
+
collection,
|
|
186
|
+
field,
|
|
187
|
+
item
|
|
188
|
+
};
|
|
189
|
+
//# sourceMappingURL=dsl.js.map
|
package/dist/dsl.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../schema/src/types.ts","../../schema/src/fields.ts","../../schema/src/collection.ts"],"sourcesContent":["/**\n * Canonical schema representation (SPEC 6.2 / 7).\n *\n * These are the normalized, serializable shapes stored as `schema_json`. Field\n * order is significant and preserved as an array; object *keys* are sorted only\n * during canonical stringification for a stable hash.\n */\n\nexport type FieldType =\n | \"text\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"datetime\"\n | \"markdown\"\n | \"json\"\n | \"asset\"\n | \"reference\"\n | \"list\"\n | \"object\"\n | \"slug\";\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n/** UI metadata carried on every field (non-semantic, does not affect validation). */\nexport interface FieldUi {\n widget?: string;\n placeholder?: string;\n helpText?: string;\n group?: string;\n hidden?: boolean;\n}\n\ninterface FieldBase {\n key: string;\n type: FieldType;\n label: string;\n description?: string;\n required: boolean;\n ui?: FieldUi;\n}\n\nexport interface TextField extends FieldBase {\n type: \"text\";\n multiline: boolean;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n default?: string;\n}\n\nexport interface NumberField extends FieldBase {\n type: \"number\";\n integer: boolean;\n min?: number;\n max?: number;\n default?: number;\n}\n\nexport interface BooleanField extends FieldBase {\n type: \"boolean\";\n default?: boolean;\n}\n\nexport interface DateField extends FieldBase {\n type: \"date\" | \"datetime\";\n min?: string;\n max?: string;\n default?: string;\n}\n\nexport interface MarkdownField extends FieldBase {\n type: \"markdown\";\n minLength?: number;\n maxLength?: number;\n default?: string;\n}\n\nexport interface JsonField extends FieldBase {\n type: \"json\";\n default?: JsonValue;\n}\n\nexport interface AssetField extends FieldBase {\n type: \"asset\";\n /** Allowed MIME families, e.g. `image/*`, `application/pdf`. */\n allowed: string[];\n multiple: boolean;\n}\n\nexport interface ReferenceField extends FieldBase {\n type: \"reference\";\n /** Target collection key. */\n target: string;\n multiple: boolean;\n}\n\nexport interface SlugField extends FieldBase {\n type: \"slug\";\n /** Source field key to derive the slug from. */\n from?: string;\n}\n\nexport type PrimitiveItem =\n | { kind: \"text\"; minLength?: number; maxLength?: number; pattern?: string; enum?: string[] }\n | { kind: \"number\"; integer?: boolean; min?: number; max?: number }\n | { kind: \"boolean\" }\n | { kind: \"date\" | \"datetime\"; min?: string; max?: string }\n | { kind: \"markdown\"; minLength?: number; maxLength?: number }\n | { kind: \"json\" };\n\nexport type ListItem =\n | PrimitiveItem\n | { kind: \"reference\"; target: string }\n | { kind: \"asset\"; allowed: string[] }\n | { kind: \"object\"; fields: FieldDef[] };\n\nexport interface ListField extends FieldBase {\n type: \"list\";\n item: ListItem;\n minItems?: number;\n maxItems?: number;\n}\n\nexport interface ObjectField extends FieldBase {\n type: \"object\";\n fields: FieldDef[];\n}\n\nexport type FieldDef =\n | TextField\n | NumberField\n | BooleanField\n | DateField\n | MarkdownField\n | JsonField\n | AssetField\n | ReferenceField\n | SlugField\n | ListField\n | ObjectField;\n\nexport type CollectionKind = \"collection\" | \"singleton\";\nexport type Visibility = \"public\" | \"private\";\n\nexport interface SlugConfig {\n from: string;\n required: boolean;\n}\n\n/** Canonical collection schema (one `collection_versions.schema_json`). */\nexport interface CollectionSchema {\n name: string;\n label: string;\n kind: CollectionKind;\n visibility: Visibility;\n titleField: string | null;\n slug: SlugConfig | null;\n path: string | null;\n fields: FieldDef[];\n}\n\n/** Maximum object/list nesting depth (SPEC 6.2). */\nexport const MAX_NESTING_DEPTH = 4;\n","import type {\n AssetField,\n BooleanField,\n DateField,\n FieldDef,\n FieldUi,\n JsonField,\n JsonValue,\n ListField,\n ListItem,\n MarkdownField,\n NumberField,\n ObjectField,\n ReferenceField,\n SlugField,\n TextField,\n} from \"./types.js\";\n\n/** A field definition before its `key` is assigned by `collection()`. */\nexport type FieldInput = DistributiveOmit<FieldDef, \"key\">;\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\n\ninterface CommonOptions {\n label?: string;\n description?: string;\n required?: boolean;\n ui?: FieldUi;\n}\n\nfunction common(o: CommonOptions): { label?: string; description?: string; required: boolean; ui?: FieldUi } {\n const base: { label?: string; description?: string; required: boolean; ui?: FieldUi } = {\n required: o.required ?? false,\n };\n if (o.label !== undefined) base.label = o.label;\n if (o.description !== undefined) base.description = o.description;\n if (o.ui !== undefined) base.ui = o.ui;\n return base;\n}\n\nexport interface TextOptions extends CommonOptions {\n multiline?: boolean;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n enum?: string[];\n default?: string;\n}\nexport interface NumberOptions extends CommonOptions {\n integer?: boolean;\n min?: number;\n max?: number;\n default?: number;\n}\nexport interface BooleanOptions extends CommonOptions {\n default?: boolean;\n}\nexport interface DateOptions extends CommonOptions {\n min?: string;\n max?: string;\n default?: string;\n}\nexport interface MarkdownOptions extends CommonOptions {\n minLength?: number;\n maxLength?: number;\n default?: string;\n}\nexport interface JsonOptions extends CommonOptions {\n default?: JsonValue;\n}\nexport interface AssetOptions extends CommonOptions {\n allowed?: string[];\n multiple?: boolean;\n}\nexport interface ReferenceOptions extends CommonOptions {\n to: string;\n multiple?: boolean;\n}\nexport interface SlugOptions extends CommonOptions {\n from?: string;\n}\nexport interface ListOptions extends CommonOptions {\n of: ListItem;\n minItems?: number;\n maxItems?: number;\n}\nexport interface ObjectOptions extends CommonOptions {\n fields: Record<string, FieldInput>;\n}\n\nfunction defined<T extends Record<string, unknown>>(obj: T): T {\n for (const key of Object.keys(obj)) {\n if (obj[key] === undefined) delete obj[key];\n }\n return obj;\n}\n\nexport const field = {\n text(o: TextOptions = {}): Omit<TextField, \"key\"> {\n return defined({\n type: \"text\",\n ...common(o),\n multiline: o.multiline ?? false,\n minLength: o.minLength,\n maxLength: o.maxLength,\n pattern: o.pattern,\n enum: o.enum,\n default: o.default,\n }) as Omit<TextField, \"key\">;\n },\n\n number(o: NumberOptions = {}): Omit<NumberField, \"key\"> {\n return defined({\n type: \"number\",\n ...common(o),\n integer: o.integer ?? false,\n min: o.min,\n max: o.max,\n default: o.default,\n }) as Omit<NumberField, \"key\">;\n },\n\n boolean(o: BooleanOptions = {}): Omit<BooleanField, \"key\"> {\n return defined({\n type: \"boolean\",\n ...common(o),\n default: o.default,\n }) as Omit<BooleanField, \"key\">;\n },\n\n date(o: DateOptions = {}): Omit<DateField, \"key\"> {\n return defined({\n type: \"date\",\n ...common(o),\n min: o.min,\n max: o.max,\n default: o.default,\n }) as Omit<DateField, \"key\">;\n },\n\n datetime(o: DateOptions = {}): Omit<DateField, \"key\"> {\n return defined({\n type: \"datetime\",\n ...common(o),\n min: o.min,\n max: o.max,\n default: o.default,\n }) as Omit<DateField, \"key\">;\n },\n\n markdown(o: MarkdownOptions = {}): Omit<MarkdownField, \"key\"> {\n return defined({\n type: \"markdown\",\n ...common(o),\n minLength: o.minLength,\n maxLength: o.maxLength,\n default: o.default,\n }) as Omit<MarkdownField, \"key\">;\n },\n\n json(o: JsonOptions = {}): Omit<JsonField, \"key\"> {\n return defined({\n type: \"json\",\n ...common(o),\n default: o.default,\n }) as Omit<JsonField, \"key\">;\n },\n\n asset(o: AssetOptions = {}): Omit<AssetField, \"key\"> {\n return defined({\n type: \"asset\",\n ...common(o),\n allowed: o.allowed ?? [\"*/*\"],\n multiple: o.multiple ?? false,\n }) as Omit<AssetField, \"key\">;\n },\n\n reference(o: ReferenceOptions): Omit<ReferenceField, \"key\"> {\n return defined({\n type: \"reference\",\n ...common(o),\n target: o.to,\n multiple: o.multiple ?? false,\n }) as Omit<ReferenceField, \"key\">;\n },\n\n slug(o: SlugOptions = {}): Omit<SlugField, \"key\"> {\n return defined({\n type: \"slug\",\n ...common(o),\n from: o.from,\n }) as Omit<SlugField, \"key\">;\n },\n\n list(o: ListOptions): Omit<ListField, \"key\"> {\n return defined({\n type: \"list\",\n ...common(o),\n item: o.of,\n minItems: o.minItems,\n maxItems: o.maxItems,\n }) as Omit<ListField, \"key\">;\n },\n\n object(o: ObjectOptions): Omit<ObjectField, \"key\"> {\n return defined({\n type: \"object\",\n ...common(o),\n fields: assignKeys(o.fields),\n }) as Omit<ObjectField, \"key\">;\n },\n} as const;\n\n/** Item builders for `field.list({ of: item.<type>() })`. */\nexport const item = {\n text(o: { minLength?: number; maxLength?: number; pattern?: string; enum?: string[] } = {}): ListItem {\n return defined({ kind: \"text\", ...o }) as ListItem;\n },\n number(o: { integer?: boolean; min?: number; max?: number } = {}): ListItem {\n return defined({ kind: \"number\", ...o }) as ListItem;\n },\n boolean(): ListItem {\n return { kind: \"boolean\" };\n },\n date(o: { min?: string; max?: string } = {}): ListItem {\n return defined({ kind: \"date\", ...o }) as ListItem;\n },\n datetime(o: { min?: string; max?: string } = {}): ListItem {\n return defined({ kind: \"datetime\", ...o }) as ListItem;\n },\n markdown(o: { minLength?: number; maxLength?: number } = {}): ListItem {\n return defined({ kind: \"markdown\", ...o }) as ListItem;\n },\n json(): ListItem {\n return { kind: \"json\" };\n },\n reference(o: { to: string }): ListItem {\n return { kind: \"reference\", target: o.to };\n },\n asset(o: { allowed?: string[] } = {}): ListItem {\n return { kind: \"asset\", allowed: o.allowed ?? [\"*/*\"] };\n },\n object(o: { fields: Record<string, FieldInput> }): ListItem {\n return { kind: \"object\", fields: assignKeys(o.fields) };\n },\n} as const;\n\n/** Turn a `{ key: FieldInput }` map into an ordered array of `FieldDef`. */\nexport function assignKeys(fields: Record<string, FieldInput>): FieldDef[] {\n return Object.entries(fields).map(([key, def]) => ({ key, ...def }) as FieldDef);\n}\n","import { assignKeys, type FieldInput } from \"./fields.js\";\nimport type { CollectionKind, CollectionSchema, SlugConfig, Visibility } from \"./types.js\";\n\nexport interface CollectionInput {\n /** Immutable collection key, e.g. `posts`. */\n name: string;\n label?: string;\n kind?: CollectionKind;\n /** Visibility defaults to `private` and must be explicitly declared `public`. */\n visibility?: Visibility;\n titleField?: string;\n /** Path template such as `/blog/{slug}`. */\n path?: string;\n fields: Record<string, FieldInput>;\n}\n\n/**\n * Author a collection schema. Returns the canonical `CollectionSchema` with an\n * ordered fields array. Defaults: `kind=collection`, `visibility=private`.\n */\nexport function collection(input: CollectionInput): CollectionSchema {\n const fields = assignKeys(input.fields);\n const slugField = fields.find((f) => f.type === \"slug\");\n\n let slug: SlugConfig | null = null;\n if (slugField && slugField.type === \"slug\") {\n slug = {\n from: slugField.from ?? input.titleField ?? slugField.key,\n required: slugField.required,\n };\n }\n\n return {\n name: input.name,\n label: input.label ?? input.name,\n kind: input.kind ?? \"collection\",\n visibility: input.visibility ?? \"private\",\n titleField: input.titleField ?? null,\n slug,\n path: input.path ?? null,\n fields,\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/main.js
CHANGED
|
@@ -945,9 +945,14 @@ function registerAuth(program) {
|
|
|
945
945
|
handle(async (ctx) => {
|
|
946
946
|
const token = ctx.token ?? loadToken(ctx.apiUrl);
|
|
947
947
|
if (!token) throw new CliError("Not authenticated. Run `myna login`.");
|
|
948
|
-
const
|
|
948
|
+
const identityResponse = await fetch(`${ctx.apiUrl}/v1/auth/whoami`, {
|
|
949
949
|
headers: { authorization: `Bearer ${token}`, accept: "application/json" }
|
|
950
|
-
})
|
|
950
|
+
});
|
|
951
|
+
const identityBody = await identityResponse.json().catch(() => ({}));
|
|
952
|
+
if (!identityResponse.ok || !identityBody.data) {
|
|
953
|
+
throw new CliError(identityBody.detail ?? "Stored credential is invalid. Run `myna login` again.");
|
|
954
|
+
}
|
|
955
|
+
const identity = identityBody.data;
|
|
951
956
|
let organization;
|
|
952
957
|
if (ctx.organization) {
|
|
953
958
|
organization = await ctx.management().organizations.get(ctx.organization).then((o) => ({ name: o.name, role: o.role, slug: o.slug })).catch((e) => {
|
|
@@ -955,12 +960,12 @@ function registerAuth(program) {
|
|
|
955
960
|
throw e;
|
|
956
961
|
});
|
|
957
962
|
}
|
|
958
|
-
emit({ apiUrl: ctx.apiUrl, authenticated: true,
|
|
963
|
+
emit({ apiUrl: ctx.apiUrl, authenticated: true, identity, organization: organization ?? null }, () => {
|
|
959
964
|
const pairs = [["API", ctx.apiUrl], ["Authenticated", "yes"]];
|
|
960
|
-
if (
|
|
961
|
-
pairs.push(["User",
|
|
965
|
+
if (identity.credential === "user") {
|
|
966
|
+
pairs.push(["User", identity.user?.username ?? "(unknown)"]);
|
|
962
967
|
} else {
|
|
963
|
-
pairs.push(["Credential", "API token"]);
|
|
968
|
+
pairs.push(["Credential", identity.credential === "api_key" ? "API key" : "Preview token"]);
|
|
964
969
|
}
|
|
965
970
|
if (organization) pairs.push(["Organization", `${organization.name} (${organization.role})`]);
|
|
966
971
|
keyValues(pairs);
|
|
@@ -972,7 +977,7 @@ function registerAuth(program) {
|
|
|
972
977
|
// src/commands/workspace.ts
|
|
973
978
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
974
979
|
import { join as join2 } from "path";
|
|
975
|
-
var EXAMPLE_SCHEMA = `import { collection, field } from "@myna-sh/schema";
|
|
980
|
+
var EXAMPLE_SCHEMA = `import { collection, field } from "@myna-sh/sdk/schema";
|
|
976
981
|
|
|
977
982
|
/**
|
|
978
983
|
* Example collection. Edit freely, then run:
|
|
@@ -1103,6 +1108,7 @@ import { join as join4 } from "path";
|
|
|
1103
1108
|
// src/schema-loader.ts
|
|
1104
1109
|
import { existsSync as existsSync3, readdirSync, statSync } from "fs";
|
|
1105
1110
|
import { join as join3, resolve as resolve2 } from "path";
|
|
1111
|
+
import { fileURLToPath } from "url";
|
|
1106
1112
|
import { build } from "esbuild";
|
|
1107
1113
|
|
|
1108
1114
|
// ../schema/dist/canonical.js
|
|
@@ -1130,6 +1136,18 @@ function toCanonical(schema) {
|
|
|
1130
1136
|
|
|
1131
1137
|
// src/schema-loader.ts
|
|
1132
1138
|
var DEFAULT_SCHEMA_DIR = "myna";
|
|
1139
|
+
function dslAliasPlugin() {
|
|
1140
|
+
let dslPath = fileURLToPath(new URL("./dsl.js", import.meta.url));
|
|
1141
|
+
if (!existsSync3(dslPath)) dslPath = dslPath.replace(/\.js$/, ".ts");
|
|
1142
|
+
return {
|
|
1143
|
+
name: "myna-dsl-alias",
|
|
1144
|
+
setup(builder) {
|
|
1145
|
+
builder.onResolve({ filter: /^@myna-sh\/(schema|sdk\/schema)$/ }, () => ({
|
|
1146
|
+
path: dslPath
|
|
1147
|
+
}));
|
|
1148
|
+
}
|
|
1149
|
+
};
|
|
1150
|
+
}
|
|
1133
1151
|
function looksLikeCollection(value) {
|
|
1134
1152
|
return typeof value === "object" && value !== null && typeof value.name === "string" && Array.isArray(value.fields);
|
|
1135
1153
|
}
|
|
@@ -1176,7 +1194,8 @@ async function loadLocalSchemas(schemaDir = DEFAULT_SCHEMA_DIR) {
|
|
|
1176
1194
|
platform: "node",
|
|
1177
1195
|
target: "node20",
|
|
1178
1196
|
logLevel: "silent",
|
|
1179
|
-
absWorkingDir: process.cwd()
|
|
1197
|
+
absWorkingDir: process.cwd(),
|
|
1198
|
+
plugins: [dslAliasPlugin()]
|
|
1180
1199
|
}).catch((error) => {
|
|
1181
1200
|
throw new CliError(`Failed to compile ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
1182
1201
|
});
|
|
@@ -1214,7 +1233,7 @@ function schemaToDsl(schema) {
|
|
|
1214
1233
|
if (schema.path) opts.push(`path: ${str(schema.path)}`);
|
|
1215
1234
|
const fieldLines = schema.fields.map((f) => ` ${ident(f.key)}: ${emitField(f)},`).join("\n");
|
|
1216
1235
|
return [
|
|
1217
|
-
`import { collection, field, item } from "@myna-sh/schema";`,
|
|
1236
|
+
`import { collection, field, item } from "@myna-sh/sdk/schema";`,
|
|
1218
1237
|
``,
|
|
1219
1238
|
`export const ${varName(schema.name)} = collection({`,
|
|
1220
1239
|
` ${opts.join(",\n ")},`,
|
|
@@ -1874,6 +1893,38 @@ function registerProjects(program) {
|
|
|
1874
1893
|
);
|
|
1875
1894
|
})
|
|
1876
1895
|
);
|
|
1896
|
+
projects.command("update").description("Update project settings").argument("[project]", "project id or slug").option("--name <name>", "project name").option("--timezone <timezone>", "IANA timezone").option("--public-api <state>", "public API state (on|off)").option("--default-preview-template <template>", "default preview URL template").option("--clear-default-preview-template", "remove the default preview URL template").option("--origins <urls>", "comma-separated allowed origins").option("--clear-origins", "remove all allowed origins").action(
|
|
1897
|
+
handle(async (ctx, args, opts) => {
|
|
1898
|
+
const ref = args[0] ?? ctx.requireProject();
|
|
1899
|
+
const patch = {};
|
|
1900
|
+
if (opts.name !== void 0) patch.name = opts.name;
|
|
1901
|
+
if (opts.timezone !== void 0) patch.timezone = opts.timezone;
|
|
1902
|
+
if (opts.publicApi !== void 0) {
|
|
1903
|
+
const state = String(opts.publicApi).toLowerCase();
|
|
1904
|
+
if (!["on", "off", "true", "false"].includes(state)) {
|
|
1905
|
+
throw new UsageError("--public-api must be on or off.");
|
|
1906
|
+
}
|
|
1907
|
+
patch.publicApiEnabled = state === "on" || state === "true";
|
|
1908
|
+
}
|
|
1909
|
+
if (opts.defaultPreviewTemplate !== void 0 && opts.clearDefaultPreviewTemplate) {
|
|
1910
|
+
throw new UsageError("Use either --default-preview-template or --clear-default-preview-template, not both.");
|
|
1911
|
+
}
|
|
1912
|
+
if (opts.defaultPreviewTemplate !== void 0) {
|
|
1913
|
+
patch.defaultPreviewTemplate = opts.defaultPreviewTemplate;
|
|
1914
|
+
}
|
|
1915
|
+
if (opts.clearDefaultPreviewTemplate) patch.defaultPreviewTemplate = null;
|
|
1916
|
+
if (opts.origins !== void 0 && opts.clearOrigins) {
|
|
1917
|
+
throw new UsageError("Use either --origins or --clear-origins, not both.");
|
|
1918
|
+
}
|
|
1919
|
+
if (opts.origins !== void 0) patch.origins = csv(opts.origins);
|
|
1920
|
+
if (opts.clearOrigins) patch.origins = [];
|
|
1921
|
+
if (Object.keys(patch).length === 0) {
|
|
1922
|
+
throw new UsageError("Specify at least one project setting to update.");
|
|
1923
|
+
}
|
|
1924
|
+
const project = await ctx.management().projects.update(ref, patch);
|
|
1925
|
+
emit(project, () => diag(`Updated ${project.slug}.`));
|
|
1926
|
+
})
|
|
1927
|
+
);
|
|
1877
1928
|
projects.command("archive").description("Archive a project").argument("[project]", "project id or slug").action(
|
|
1878
1929
|
handle(async (ctx, args) => {
|
|
1879
1930
|
const ref = args[0] ?? ctx.requireProject();
|
|
@@ -2116,7 +2167,7 @@ function registerBilling(program) {
|
|
|
2116
2167
|
}
|
|
2117
2168
|
|
|
2118
2169
|
// src/main.ts
|
|
2119
|
-
var VERSION = "0.1.
|
|
2170
|
+
var VERSION = "0.1.4";
|
|
2120
2171
|
var GLOBAL_VALUE_FLAGS = /* @__PURE__ */ new Set(["--project", "--organization", "--token", "--api-url"]);
|
|
2121
2172
|
var GLOBAL_BOOL_FLAGS = /* @__PURE__ */ new Set(["--json", "--no-interactive", "--interactive"]);
|
|
2122
2173
|
function normalizeGlobals(argv) {
|