@myna-sh/cli 0.1.0 → 0.1.3
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 +21 -0
- package/README.md +52 -0
- package/dist/dsl.d.ts +276 -0
- package/dist/dsl.js +189 -0
- package/dist/dsl.js.map +1 -0
- package/dist/main.js +29 -10
- package/dist/main.js.map +1 -1
- package/package.json +17 -21
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tiago Mouta
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @myna-sh/cli
|
|
2
|
+
|
|
3
|
+
Command-line client for [Myna](https://myna.sh), the agent-native headless CMS.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install --global @myna-sh/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run it without installing:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npx @myna-sh/cli --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Authenticate
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
myna login
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The CLI opens `app.myna.sh/device`, where you sign in with GitHub and approve the one-time device code. The resulting credential is stored in the macOS Keychain when available, otherwise in a user-only configuration file.
|
|
24
|
+
|
|
25
|
+
## Start a project
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
myna organizations list
|
|
29
|
+
myna projects list --organization my-organization
|
|
30
|
+
myna link --organization my-organization --project my-project
|
|
31
|
+
myna entries list posts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run `myna --help` or `myna <command> --help` for the complete command reference. Global flags include `--json`, `--organization`, `--project`, `--token`, and `--api-url`.
|
|
35
|
+
|
|
36
|
+
## Environment
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
MYNA_API_URL API origin; defaults to https://api.myna.sh
|
|
40
|
+
MYNA_TOKEN Scoped API credential
|
|
41
|
+
MYNA_ORGANIZATION Default organization ID or slug
|
|
42
|
+
MYNA_PROJECT Default project ID or slug
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Links
|
|
46
|
+
|
|
47
|
+
- [Myna](https://myna.sh)
|
|
48
|
+
- Support: [support@myna.sh](mailto:support@myna.sh)
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
MIT
|
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 ")},`,
|
|
@@ -2116,7 +2135,7 @@ function registerBilling(program) {
|
|
|
2116
2135
|
}
|
|
2117
2136
|
|
|
2118
2137
|
// src/main.ts
|
|
2119
|
-
var VERSION = "0.1.
|
|
2138
|
+
var VERSION = "0.1.3";
|
|
2120
2139
|
var GLOBAL_VALUE_FLAGS = /* @__PURE__ */ new Set(["--project", "--organization", "--token", "--api-url"]);
|
|
2121
2140
|
var GLOBAL_BOOL_FLAGS = /* @__PURE__ */ new Set(["--json", "--no-interactive", "--interactive"]);
|
|
2122
2141
|
function normalizeGlobals(argv) {
|