@adminiumjs/manifest 0.1.0 → 0.1.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/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +530 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +279 -0
- package/dist/schema.js.map +1 -0
- package/dist/validate.d.ts +34 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +44 -0
- package/dist/validate.js.map +1 -0
- package/package.json +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @adminium/manifest — Micro-SaaS manifest spec v1 (13-marketplace.md §2).
|
|
3
|
+
*
|
|
4
|
+
* Wave 1: the frozen envelope schema + validator (browser-safe, pure Zod).
|
|
5
|
+
* The install planner (requiredSchema → create-or-map diff) and the
|
|
6
|
+
* server-side installer land in later waves and consume a validated manifest.
|
|
7
|
+
*/
|
|
2
8
|
export declare const PACKAGE_NAME = "@adminium/manifest";
|
|
9
|
+
export { MANIFEST_VERSION, MANIFEST_CATEGORIES, MANIFEST_CAPABILITIES, COLUMN_TYPES, COLUMN_SEMANTICS, COLUMN_ROLES, FRONTEND_KINDS, FIRST_PARTY_PUBLISHER_ID, manifestSchema, identitySchema, compatibilitySchema, requiredSchemaSchema, requiredTableSchema, requiredColumnSchema, pageSchema, roleSchema, settingSchema, seedSchema, frontendSchema, capabilitySchema, categorySchema, publisherSchema, i18nMessageSchema, compareSemver, type Manifest, type Capability, type Publisher, type I18nMessage, } from './schema.js';
|
|
10
|
+
export { validateManifest, parseManifest, type ValidateManifestResult, type ValidateManifestOptions, type ManifestIssue, } from './validate.js';
|
|
3
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,uBAAuB,CAAC;AAEjD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* @adminium/manifest — Micro-SaaS manifest spec v1 (13-marketplace.md §2).
|
|
3
|
+
*
|
|
4
|
+
* Wave 1: the frozen envelope schema + validator (browser-safe, pure Zod).
|
|
5
|
+
* The install planner (requiredSchema → create-or-map diff) and the
|
|
6
|
+
* server-side installer land in later waves and consume a validated manifest.
|
|
7
|
+
*/
|
|
2
8
|
export const PACKAGE_NAME = '@adminium/manifest';
|
|
9
|
+
export { MANIFEST_VERSION, MANIFEST_CATEGORIES, MANIFEST_CAPABILITIES, COLUMN_TYPES, COLUMN_SEMANTICS, COLUMN_ROLES, FRONTEND_KINDS, FIRST_PARTY_PUBLISHER_ID, manifestSchema, identitySchema, compatibilitySchema, requiredSchemaSchema, requiredTableSchema, requiredColumnSchema, pageSchema, roleSchema, settingSchema, seedSchema, frontendSchema, capabilitySchema, categorySchema, publisherSchema, i18nMessageSchema, compareSemver, } from './schema.js';
|
|
10
|
+
export { validateManifest, parseManifest, } from './validate.js';
|
|
3
11
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEjD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,wBAAwB,EACxB,cAAc,EACd,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,aAAa,GAKd,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,gBAAgB,EAChB,aAAa,GAId,MAAM,eAAe,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest spec v1 (13-marketplace.md §2), frozen at `manifestVersion: 1` for
|
|
3
|
+
* all of Adminium 1.x. Pure Zod v4 + types — no `node:` imports — so the
|
|
4
|
+
* storefront and the Electron shell can validate a manifest in the browser
|
|
5
|
+
* (01-architecture.md §3, the `@adminium/manifest` package row).
|
|
6
|
+
*
|
|
7
|
+
* This module is the envelope: every block's shape and the cross-block rules.
|
|
8
|
+
* The install PLANNER (planInstall / requiredSchema → create-or-map diff) and
|
|
9
|
+
* the server-side installer are later layers that consume a validated manifest.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
/** Integer spec version, frozen at 1 for Adminium 1.x (§2, 01 §8). */
|
|
13
|
+
export declare const MANIFEST_VERSION = 1;
|
|
14
|
+
/** An i18n message: a catalog key plus the English fallback rendered if absent. */
|
|
15
|
+
export declare const i18nMessageSchema: z.ZodObject<{
|
|
16
|
+
key: z.ZodString;
|
|
17
|
+
fallback: z.ZodString;
|
|
18
|
+
}, z.core.$strict>;
|
|
19
|
+
export type I18nMessage = z.infer<typeof i18nMessageSchema>;
|
|
20
|
+
/** Closed v1 storefront facet set (§2.3). */
|
|
21
|
+
export declare const MANIFEST_CATEGORIES: readonly ["commerce", "hospitality", "operations", "crm", "internal-tools"];
|
|
22
|
+
export declare const categorySchema: z.ZodEnum<{
|
|
23
|
+
commerce: "commerce";
|
|
24
|
+
hospitality: "hospitality";
|
|
25
|
+
operations: "operations";
|
|
26
|
+
crm: "crm";
|
|
27
|
+
"internal-tools": "internal-tools";
|
|
28
|
+
}>;
|
|
29
|
+
/** The one publisher id v1 accepts unless `third-party-publishers` is on (§2.3/§9). */
|
|
30
|
+
export declare const FIRST_PARTY_PUBLISHER_ID = "adminium";
|
|
31
|
+
export declare const publisherSchema: z.ZodObject<{
|
|
32
|
+
id: z.ZodString;
|
|
33
|
+
name: z.ZodString;
|
|
34
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
export type Publisher = z.infer<typeof publisherSchema>;
|
|
37
|
+
export declare const identitySchema: z.ZodObject<{
|
|
38
|
+
key: z.ZodString;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
version: z.ZodString;
|
|
41
|
+
publisher: z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
name: z.ZodString;
|
|
44
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
license: z.ZodString;
|
|
47
|
+
description: z.ZodObject<{
|
|
48
|
+
key: z.ZodString;
|
|
49
|
+
fallback: z.ZodString;
|
|
50
|
+
}, z.core.$strict>;
|
|
51
|
+
categories: z.ZodArray<z.ZodEnum<{
|
|
52
|
+
commerce: "commerce";
|
|
53
|
+
hospitality: "hospitality";
|
|
54
|
+
operations: "operations";
|
|
55
|
+
crm: "crm";
|
|
56
|
+
"internal-tools": "internal-tools";
|
|
57
|
+
}>>;
|
|
58
|
+
}, z.core.$strict>;
|
|
59
|
+
export declare const MANIFEST_CAPABILITIES: readonly ["hosted-only", "offline-required", "receipt-printer", "barcode-scanner", "payments", "file-storage", "email-delivery", "realtime"];
|
|
60
|
+
export declare const capabilitySchema: z.ZodEnum<{
|
|
61
|
+
"hosted-only": "hosted-only";
|
|
62
|
+
"offline-required": "offline-required";
|
|
63
|
+
"receipt-printer": "receipt-printer";
|
|
64
|
+
"barcode-scanner": "barcode-scanner";
|
|
65
|
+
payments: "payments";
|
|
66
|
+
"file-storage": "file-storage";
|
|
67
|
+
"email-delivery": "email-delivery";
|
|
68
|
+
realtime: "realtime";
|
|
69
|
+
}>;
|
|
70
|
+
export type Capability = z.infer<typeof capabilitySchema>;
|
|
71
|
+
export declare const compatibilitySchema: z.ZodObject<{
|
|
72
|
+
minAdminiumVersion: z.ZodString;
|
|
73
|
+
maxAdminiumVersion: z.ZodOptional<z.ZodString>;
|
|
74
|
+
requires: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
75
|
+
"hosted-only": "hosted-only";
|
|
76
|
+
"offline-required": "offline-required";
|
|
77
|
+
"receipt-printer": "receipt-printer";
|
|
78
|
+
"barcode-scanner": "barcode-scanner";
|
|
79
|
+
payments: "payments";
|
|
80
|
+
"file-storage": "file-storage";
|
|
81
|
+
"email-delivery": "email-delivery";
|
|
82
|
+
realtime: "realtime";
|
|
83
|
+
}>>>;
|
|
84
|
+
}, z.core.$strict>;
|
|
85
|
+
/** Abstract column types the introspection engine emits (§2.5, research §15.2). */
|
|
86
|
+
export declare const COLUMN_TYPES: readonly ["id", "text", "int", "bigint", "decimal", "money", "float", "bool", "enum", "json", "date", "timestamptz", "uuid", "fk", "blob"];
|
|
87
|
+
/** Optional semantic pre-seed so widgets auto-instantiate (§2.5). */
|
|
88
|
+
export declare const COLUMN_SEMANTICS: readonly ["name", "money", "image", "email", "avatar", "geo-lat", "geo-lng"];
|
|
89
|
+
/** Structural role markers (§2.5). */
|
|
90
|
+
export declare const COLUMN_ROLES: readonly ["pk", "created_at", "updated_at"];
|
|
91
|
+
export declare const requiredColumnSchema: z.ZodObject<{
|
|
92
|
+
ref: z.ZodString;
|
|
93
|
+
type: z.ZodEnum<{
|
|
94
|
+
bigint: "bigint";
|
|
95
|
+
id: "id";
|
|
96
|
+
int: "int";
|
|
97
|
+
date: "date";
|
|
98
|
+
enum: "enum";
|
|
99
|
+
text: "text";
|
|
100
|
+
decimal: "decimal";
|
|
101
|
+
money: "money";
|
|
102
|
+
float: "float";
|
|
103
|
+
bool: "bool";
|
|
104
|
+
json: "json";
|
|
105
|
+
timestamptz: "timestamptz";
|
|
106
|
+
uuid: "uuid";
|
|
107
|
+
fk: "fk";
|
|
108
|
+
blob: "blob";
|
|
109
|
+
}>;
|
|
110
|
+
semantic: z.ZodOptional<z.ZodEnum<{
|
|
111
|
+
name: "name";
|
|
112
|
+
money: "money";
|
|
113
|
+
image: "image";
|
|
114
|
+
email: "email";
|
|
115
|
+
avatar: "avatar";
|
|
116
|
+
"geo-lat": "geo-lat";
|
|
117
|
+
"geo-lng": "geo-lng";
|
|
118
|
+
}>>;
|
|
119
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
120
|
+
pk: "pk";
|
|
121
|
+
created_at: "created_at";
|
|
122
|
+
updated_at: "updated_at";
|
|
123
|
+
}>>;
|
|
124
|
+
nullable: z.ZodOptional<z.ZodBoolean>;
|
|
125
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
126
|
+
references: z.ZodOptional<z.ZodString>;
|
|
127
|
+
}, z.core.$strict>;
|
|
128
|
+
export declare const requiredTableSchema: z.ZodObject<{
|
|
129
|
+
ref: z.ZodString;
|
|
130
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
131
|
+
ref: z.ZodString;
|
|
132
|
+
type: z.ZodEnum<{
|
|
133
|
+
bigint: "bigint";
|
|
134
|
+
id: "id";
|
|
135
|
+
int: "int";
|
|
136
|
+
date: "date";
|
|
137
|
+
enum: "enum";
|
|
138
|
+
text: "text";
|
|
139
|
+
decimal: "decimal";
|
|
140
|
+
money: "money";
|
|
141
|
+
float: "float";
|
|
142
|
+
bool: "bool";
|
|
143
|
+
json: "json";
|
|
144
|
+
timestamptz: "timestamptz";
|
|
145
|
+
uuid: "uuid";
|
|
146
|
+
fk: "fk";
|
|
147
|
+
blob: "blob";
|
|
148
|
+
}>;
|
|
149
|
+
semantic: z.ZodOptional<z.ZodEnum<{
|
|
150
|
+
name: "name";
|
|
151
|
+
money: "money";
|
|
152
|
+
image: "image";
|
|
153
|
+
email: "email";
|
|
154
|
+
avatar: "avatar";
|
|
155
|
+
"geo-lat": "geo-lat";
|
|
156
|
+
"geo-lng": "geo-lng";
|
|
157
|
+
}>>;
|
|
158
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
159
|
+
pk: "pk";
|
|
160
|
+
created_at: "created_at";
|
|
161
|
+
updated_at: "updated_at";
|
|
162
|
+
}>>;
|
|
163
|
+
nullable: z.ZodOptional<z.ZodBoolean>;
|
|
164
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
165
|
+
references: z.ZodOptional<z.ZodString>;
|
|
166
|
+
}, z.core.$strict>>;
|
|
167
|
+
}, z.core.$strict>;
|
|
168
|
+
export declare const requiredSchemaSchema: z.ZodObject<{
|
|
169
|
+
tables: z.ZodArray<z.ZodObject<{
|
|
170
|
+
ref: z.ZodString;
|
|
171
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
172
|
+
ref: z.ZodString;
|
|
173
|
+
type: z.ZodEnum<{
|
|
174
|
+
bigint: "bigint";
|
|
175
|
+
id: "id";
|
|
176
|
+
int: "int";
|
|
177
|
+
date: "date";
|
|
178
|
+
enum: "enum";
|
|
179
|
+
text: "text";
|
|
180
|
+
decimal: "decimal";
|
|
181
|
+
money: "money";
|
|
182
|
+
float: "float";
|
|
183
|
+
bool: "bool";
|
|
184
|
+
json: "json";
|
|
185
|
+
timestamptz: "timestamptz";
|
|
186
|
+
uuid: "uuid";
|
|
187
|
+
fk: "fk";
|
|
188
|
+
blob: "blob";
|
|
189
|
+
}>;
|
|
190
|
+
semantic: z.ZodOptional<z.ZodEnum<{
|
|
191
|
+
name: "name";
|
|
192
|
+
money: "money";
|
|
193
|
+
image: "image";
|
|
194
|
+
email: "email";
|
|
195
|
+
avatar: "avatar";
|
|
196
|
+
"geo-lat": "geo-lat";
|
|
197
|
+
"geo-lng": "geo-lng";
|
|
198
|
+
}>>;
|
|
199
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
200
|
+
pk: "pk";
|
|
201
|
+
created_at: "created_at";
|
|
202
|
+
updated_at: "updated_at";
|
|
203
|
+
}>>;
|
|
204
|
+
nullable: z.ZodOptional<z.ZodBoolean>;
|
|
205
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
206
|
+
references: z.ZodOptional<z.ZodString>;
|
|
207
|
+
}, z.core.$strict>>;
|
|
208
|
+
}, z.core.$strict>>;
|
|
209
|
+
}, z.core.$strict>;
|
|
210
|
+
export declare const pageNavSchema: z.ZodObject<{
|
|
211
|
+
group: z.ZodString;
|
|
212
|
+
icon: z.ZodString;
|
|
213
|
+
order: z.ZodNumber;
|
|
214
|
+
}, z.core.$strict>;
|
|
215
|
+
export declare const pageSchema: z.ZodObject<{
|
|
216
|
+
ref: z.ZodString;
|
|
217
|
+
template: z.ZodString;
|
|
218
|
+
title: z.ZodObject<{
|
|
219
|
+
key: z.ZodString;
|
|
220
|
+
fallback: z.ZodString;
|
|
221
|
+
}, z.core.$strict>;
|
|
222
|
+
nav: z.ZodObject<{
|
|
223
|
+
group: z.ZodString;
|
|
224
|
+
icon: z.ZodString;
|
|
225
|
+
order: z.ZodNumber;
|
|
226
|
+
}, z.core.$strict>;
|
|
227
|
+
bindings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
228
|
+
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
export declare const roleSchema: z.ZodObject<{
|
|
231
|
+
key: z.ZodString;
|
|
232
|
+
name: z.ZodString;
|
|
233
|
+
cloneFrom: z.ZodOptional<z.ZodString>;
|
|
234
|
+
permissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
235
|
+
}, z.core.$strict>;
|
|
236
|
+
export declare const settingSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
237
|
+
type: z.ZodLiteral<"string">;
|
|
238
|
+
default: z.ZodOptional<z.ZodString>;
|
|
239
|
+
key: z.ZodString;
|
|
240
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
241
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
242
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
243
|
+
key: z.ZodString;
|
|
244
|
+
fallback: z.ZodString;
|
|
245
|
+
}, z.core.$strict>>;
|
|
246
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
247
|
+
type: z.ZodLiteral<"number">;
|
|
248
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
249
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
250
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
251
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
252
|
+
key: z.ZodString;
|
|
253
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
254
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
255
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
256
|
+
key: z.ZodString;
|
|
257
|
+
fallback: z.ZodString;
|
|
258
|
+
}, z.core.$strict>>;
|
|
259
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
260
|
+
type: z.ZodLiteral<"boolean">;
|
|
261
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
262
|
+
key: z.ZodString;
|
|
263
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
264
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
265
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
266
|
+
key: z.ZodString;
|
|
267
|
+
fallback: z.ZodString;
|
|
268
|
+
}, z.core.$strict>>;
|
|
269
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
270
|
+
type: z.ZodLiteral<"enum">;
|
|
271
|
+
enum: z.ZodArray<z.ZodString>;
|
|
272
|
+
default: z.ZodOptional<z.ZodString>;
|
|
273
|
+
key: z.ZodString;
|
|
274
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
275
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
276
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
277
|
+
key: z.ZodString;
|
|
278
|
+
fallback: z.ZodString;
|
|
279
|
+
}, z.core.$strict>>;
|
|
280
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
281
|
+
type: z.ZodLiteral<"file">;
|
|
282
|
+
accept: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
283
|
+
key: z.ZodString;
|
|
284
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
285
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
286
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
287
|
+
key: z.ZodString;
|
|
288
|
+
fallback: z.ZodString;
|
|
289
|
+
}, z.core.$strict>>;
|
|
290
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
291
|
+
type: z.ZodLiteral<"json">;
|
|
292
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
293
|
+
key: z.ZodString;
|
|
294
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
295
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
296
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
297
|
+
key: z.ZodString;
|
|
298
|
+
fallback: z.ZodString;
|
|
299
|
+
}, z.core.$strict>>;
|
|
300
|
+
}, z.core.$strict>], "type">;
|
|
301
|
+
export declare const seedSchema: z.ZodObject<{
|
|
302
|
+
table: z.ZodString;
|
|
303
|
+
rows: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
304
|
+
file: z.ZodOptional<z.ZodString>;
|
|
305
|
+
}, z.core.$strict>;
|
|
306
|
+
export declare const manifestWidgetSchema: z.ZodObject<{
|
|
307
|
+
id: z.ZodString;
|
|
308
|
+
entry: z.ZodString;
|
|
309
|
+
}, z.core.$strict>;
|
|
310
|
+
export declare const FRONTEND_KINDS: readonly ["spa", "electron", "none"];
|
|
311
|
+
export declare const frontendEnvVarSchema: z.ZodObject<{
|
|
312
|
+
required: z.ZodBoolean;
|
|
313
|
+
example: z.ZodOptional<z.ZodString>;
|
|
314
|
+
}, z.core.$strict>;
|
|
315
|
+
export declare const frontendSchema: z.ZodObject<{
|
|
316
|
+
kind: z.ZodEnum<{
|
|
317
|
+
spa: "spa";
|
|
318
|
+
electron: "electron";
|
|
319
|
+
none: "none";
|
|
320
|
+
}>;
|
|
321
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
322
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
323
|
+
required: z.ZodBoolean;
|
|
324
|
+
example: z.ZodOptional<z.ZodString>;
|
|
325
|
+
}, z.core.$strict>>>;
|
|
326
|
+
}, z.core.$strict>;
|
|
327
|
+
export declare const manifestSchema: z.ZodObject<{
|
|
328
|
+
compatibility: z.ZodObject<{
|
|
329
|
+
minAdminiumVersion: z.ZodString;
|
|
330
|
+
maxAdminiumVersion: z.ZodOptional<z.ZodString>;
|
|
331
|
+
requires: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
332
|
+
"hosted-only": "hosted-only";
|
|
333
|
+
"offline-required": "offline-required";
|
|
334
|
+
"receipt-printer": "receipt-printer";
|
|
335
|
+
"barcode-scanner": "barcode-scanner";
|
|
336
|
+
payments: "payments";
|
|
337
|
+
"file-storage": "file-storage";
|
|
338
|
+
"email-delivery": "email-delivery";
|
|
339
|
+
realtime: "realtime";
|
|
340
|
+
}>>>;
|
|
341
|
+
}, z.core.$strict>;
|
|
342
|
+
requiredSchema: z.ZodObject<{
|
|
343
|
+
tables: z.ZodArray<z.ZodObject<{
|
|
344
|
+
ref: z.ZodString;
|
|
345
|
+
columns: z.ZodArray<z.ZodObject<{
|
|
346
|
+
ref: z.ZodString;
|
|
347
|
+
type: z.ZodEnum<{
|
|
348
|
+
bigint: "bigint";
|
|
349
|
+
id: "id";
|
|
350
|
+
int: "int";
|
|
351
|
+
date: "date";
|
|
352
|
+
enum: "enum";
|
|
353
|
+
text: "text";
|
|
354
|
+
decimal: "decimal";
|
|
355
|
+
money: "money";
|
|
356
|
+
float: "float";
|
|
357
|
+
bool: "bool";
|
|
358
|
+
json: "json";
|
|
359
|
+
timestamptz: "timestamptz";
|
|
360
|
+
uuid: "uuid";
|
|
361
|
+
fk: "fk";
|
|
362
|
+
blob: "blob";
|
|
363
|
+
}>;
|
|
364
|
+
semantic: z.ZodOptional<z.ZodEnum<{
|
|
365
|
+
name: "name";
|
|
366
|
+
money: "money";
|
|
367
|
+
image: "image";
|
|
368
|
+
email: "email";
|
|
369
|
+
avatar: "avatar";
|
|
370
|
+
"geo-lat": "geo-lat";
|
|
371
|
+
"geo-lng": "geo-lng";
|
|
372
|
+
}>>;
|
|
373
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
374
|
+
pk: "pk";
|
|
375
|
+
created_at: "created_at";
|
|
376
|
+
updated_at: "updated_at";
|
|
377
|
+
}>>;
|
|
378
|
+
nullable: z.ZodOptional<z.ZodBoolean>;
|
|
379
|
+
enum: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
380
|
+
references: z.ZodOptional<z.ZodString>;
|
|
381
|
+
}, z.core.$strict>>;
|
|
382
|
+
}, z.core.$strict>>;
|
|
383
|
+
}, z.core.$strict>;
|
|
384
|
+
pages: z.ZodArray<z.ZodObject<{
|
|
385
|
+
ref: z.ZodString;
|
|
386
|
+
template: z.ZodString;
|
|
387
|
+
title: z.ZodObject<{
|
|
388
|
+
key: z.ZodString;
|
|
389
|
+
fallback: z.ZodString;
|
|
390
|
+
}, z.core.$strict>;
|
|
391
|
+
nav: z.ZodObject<{
|
|
392
|
+
group: z.ZodString;
|
|
393
|
+
icon: z.ZodString;
|
|
394
|
+
order: z.ZodNumber;
|
|
395
|
+
}, z.core.$strict>;
|
|
396
|
+
bindings: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
397
|
+
config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
398
|
+
}, z.core.$strict>>;
|
|
399
|
+
roles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
400
|
+
key: z.ZodString;
|
|
401
|
+
name: z.ZodString;
|
|
402
|
+
cloneFrom: z.ZodOptional<z.ZodString>;
|
|
403
|
+
permissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
404
|
+
}, z.core.$strict>>>;
|
|
405
|
+
settings: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
406
|
+
type: z.ZodLiteral<"string">;
|
|
407
|
+
default: z.ZodOptional<z.ZodString>;
|
|
408
|
+
key: z.ZodString;
|
|
409
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
410
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
411
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
412
|
+
key: z.ZodString;
|
|
413
|
+
fallback: z.ZodString;
|
|
414
|
+
}, z.core.$strict>>;
|
|
415
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
416
|
+
type: z.ZodLiteral<"number">;
|
|
417
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
418
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
419
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
420
|
+
unit: z.ZodOptional<z.ZodString>;
|
|
421
|
+
key: z.ZodString;
|
|
422
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
423
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
424
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
425
|
+
key: z.ZodString;
|
|
426
|
+
fallback: z.ZodString;
|
|
427
|
+
}, z.core.$strict>>;
|
|
428
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
429
|
+
type: z.ZodLiteral<"boolean">;
|
|
430
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
431
|
+
key: z.ZodString;
|
|
432
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
433
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
434
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
435
|
+
key: z.ZodString;
|
|
436
|
+
fallback: z.ZodString;
|
|
437
|
+
}, z.core.$strict>>;
|
|
438
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
439
|
+
type: z.ZodLiteral<"enum">;
|
|
440
|
+
enum: z.ZodArray<z.ZodString>;
|
|
441
|
+
default: z.ZodOptional<z.ZodString>;
|
|
442
|
+
key: z.ZodString;
|
|
443
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
444
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
445
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
446
|
+
key: z.ZodString;
|
|
447
|
+
fallback: z.ZodString;
|
|
448
|
+
}, z.core.$strict>>;
|
|
449
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
450
|
+
type: z.ZodLiteral<"file">;
|
|
451
|
+
accept: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
452
|
+
key: z.ZodString;
|
|
453
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
454
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
455
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
456
|
+
key: z.ZodString;
|
|
457
|
+
fallback: z.ZodString;
|
|
458
|
+
}, z.core.$strict>>;
|
|
459
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
460
|
+
type: z.ZodLiteral<"json">;
|
|
461
|
+
default: z.ZodOptional<z.ZodUnknown>;
|
|
462
|
+
key: z.ZodString;
|
|
463
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
464
|
+
secret: z.ZodOptional<z.ZodBoolean>;
|
|
465
|
+
label: z.ZodOptional<z.ZodObject<{
|
|
466
|
+
key: z.ZodString;
|
|
467
|
+
fallback: z.ZodString;
|
|
468
|
+
}, z.core.$strict>>;
|
|
469
|
+
}, z.core.$strict>], "type">>>;
|
|
470
|
+
seeds: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
471
|
+
table: z.ZodString;
|
|
472
|
+
rows: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
473
|
+
file: z.ZodOptional<z.ZodString>;
|
|
474
|
+
}, z.core.$strict>>>;
|
|
475
|
+
widgets: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
476
|
+
id: z.ZodString;
|
|
477
|
+
entry: z.ZodString;
|
|
478
|
+
}, z.core.$strict>>>;
|
|
479
|
+
capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
480
|
+
"hosted-only": "hosted-only";
|
|
481
|
+
"offline-required": "offline-required";
|
|
482
|
+
"receipt-printer": "receipt-printer";
|
|
483
|
+
"barcode-scanner": "barcode-scanner";
|
|
484
|
+
payments: "payments";
|
|
485
|
+
"file-storage": "file-storage";
|
|
486
|
+
"email-delivery": "email-delivery";
|
|
487
|
+
realtime: "realtime";
|
|
488
|
+
}>>>;
|
|
489
|
+
frontend: z.ZodObject<{
|
|
490
|
+
kind: z.ZodEnum<{
|
|
491
|
+
spa: "spa";
|
|
492
|
+
electron: "electron";
|
|
493
|
+
none: "none";
|
|
494
|
+
}>;
|
|
495
|
+
entry: z.ZodOptional<z.ZodString>;
|
|
496
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
497
|
+
required: z.ZodBoolean;
|
|
498
|
+
example: z.ZodOptional<z.ZodString>;
|
|
499
|
+
}, z.core.$strict>>>;
|
|
500
|
+
}, z.core.$strict>;
|
|
501
|
+
key: z.ZodString;
|
|
502
|
+
name: z.ZodString;
|
|
503
|
+
version: z.ZodString;
|
|
504
|
+
publisher: z.ZodObject<{
|
|
505
|
+
id: z.ZodString;
|
|
506
|
+
name: z.ZodString;
|
|
507
|
+
url: z.ZodOptional<z.ZodURL>;
|
|
508
|
+
}, z.core.$strict>;
|
|
509
|
+
license: z.ZodString;
|
|
510
|
+
description: z.ZodObject<{
|
|
511
|
+
key: z.ZodString;
|
|
512
|
+
fallback: z.ZodString;
|
|
513
|
+
}, z.core.$strict>;
|
|
514
|
+
categories: z.ZodArray<z.ZodEnum<{
|
|
515
|
+
commerce: "commerce";
|
|
516
|
+
hospitality: "hospitality";
|
|
517
|
+
operations: "operations";
|
|
518
|
+
crm: "crm";
|
|
519
|
+
"internal-tools": "internal-tools";
|
|
520
|
+
}>>;
|
|
521
|
+
manifestVersion: z.ZodLiteral<1>;
|
|
522
|
+
}, z.core.$strict>;
|
|
523
|
+
export type Manifest = z.infer<typeof manifestSchema>;
|
|
524
|
+
/**
|
|
525
|
+
* Numeric semver compare on the release triple (pre-release/build ignored —
|
|
526
|
+
* enough for the compatibility-window and upgrade ordering checks). Returns
|
|
527
|
+
* <0, 0, >0. Exported for the installer's upgrade rule (§4.3).
|
|
528
|
+
*/
|
|
529
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
530
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAOlC,mFAAmF;AACnF,eAAO,MAAM,iBAAiB;;;kBAKnB,CAAC;AACZ,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAI5D,6CAA6C;AAC7C,eAAO,MAAM,mBAAmB,6EAMtB,CAAC;AACX,eAAO,MAAM,cAAc;;;;;;EAA8B,CAAC;AAE1D,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,aAAa,CAAC;AAEnD,eAAO,MAAM,eAAe;;;;kBAMjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;kBAWhB,CAAC;AAIZ,eAAO,MAAM,qBAAqB,8IASxB,CAAC;AACX,eAAO,MAAM,gBAAgB;;;;;;;;;EAAgC,CAAC;AAC9D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAI1D,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;kBAMrB,CAAC;AAIZ,mFAAmF;AACnF,eAAO,MAAM,YAAY,4IAgBf,CAAC;AAEX,qEAAqE;AACrE,eAAO,MAAM,gBAAgB,8EAQnB,CAAC;AAEX,sCAAsC;AACtC,eAAO,MAAM,YAAY,6CAA8C,CAAC;AAExE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmB7B,CAAC;AAEL,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAS7B,CAAC;AAEJ,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQ7B,CAAC;AAIL,eAAO,MAAM,aAAa;;;;kBAMf,CAAC;AAEZ,eAAO,MAAM,UAAU;;;;;;;;;;;;;;kBAUZ,CAAC;AAIZ,eAAO,MAAM,UAAU;;;;;kBAQZ,CAAC;AAWZ,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BA6BxB,CAAC;AAIH,eAAO,MAAM,UAAU;;;;kBAUnB,CAAC;AAIL,eAAO,MAAM,oBAAoB;;;kBAKtB,CAAC;AAIZ,eAAO,MAAM,cAAc,sCAAuC,CAAC;AAEnE,eAAO,MAAM,oBAAoB;;;kBAKtB,CAAC;AAEZ,eAAO,MAAM,cAAc;;;;;;;;;;;kBAMhB,CAAC;AAIZ,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA8BxB,CAAC;AAEJ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU1D"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest spec v1 (13-marketplace.md §2), frozen at `manifestVersion: 1` for
|
|
3
|
+
* all of Adminium 1.x. Pure Zod v4 + types — no `node:` imports — so the
|
|
4
|
+
* storefront and the Electron shell can validate a manifest in the browser
|
|
5
|
+
* (01-architecture.md §3, the `@adminium/manifest` package row).
|
|
6
|
+
*
|
|
7
|
+
* This module is the envelope: every block's shape and the cross-block rules.
|
|
8
|
+
* The install PLANNER (planInstall / requiredSchema → create-or-map diff) and
|
|
9
|
+
* the server-side installer are later layers that consume a validated manifest.
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
/** Integer spec version, frozen at 1 for Adminium 1.x (§2, 01 §8). */
|
|
13
|
+
export const MANIFEST_VERSION = 1;
|
|
14
|
+
/** strict semver — `major.minor.patch` with optional pre-release/build. */
|
|
15
|
+
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
16
|
+
const semver = z.string().regex(SEMVER, 'must be strict semver (major.minor.patch)');
|
|
17
|
+
/** An i18n message: a catalog key plus the English fallback rendered if absent. */
|
|
18
|
+
export const i18nMessageSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
key: z.string().min(1).max(120),
|
|
21
|
+
fallback: z.string().min(1).max(400),
|
|
22
|
+
})
|
|
23
|
+
.strict();
|
|
24
|
+
// ── §2.3 identity ────────────────────────────────────────────────────────────
|
|
25
|
+
/** Closed v1 storefront facet set (§2.3). */
|
|
26
|
+
export const MANIFEST_CATEGORIES = [
|
|
27
|
+
'commerce',
|
|
28
|
+
'hospitality',
|
|
29
|
+
'operations',
|
|
30
|
+
'crm',
|
|
31
|
+
'internal-tools',
|
|
32
|
+
];
|
|
33
|
+
export const categorySchema = z.enum(MANIFEST_CATEGORIES);
|
|
34
|
+
/** The one publisher id v1 accepts unless `third-party-publishers` is on (§2.3/§9). */
|
|
35
|
+
export const FIRST_PARTY_PUBLISHER_ID = 'adminium';
|
|
36
|
+
export const publisherSchema = z
|
|
37
|
+
.object({
|
|
38
|
+
id: z.string().regex(/^[a-z][a-z0-9-]{1,39}$/, 'publisher id must be ^[a-z][a-z0-9-]{1,39}$'),
|
|
39
|
+
name: z.string().min(1).max(80),
|
|
40
|
+
url: z.url().max(200).optional(),
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
43
|
+
export const identitySchema = z
|
|
44
|
+
.object({
|
|
45
|
+
key: z.string().regex(/^[a-z][a-z0-9-]{1,79}$/, 'key must be ^[a-z][a-z0-9-]{1,79}$'),
|
|
46
|
+
name: z.string().min(1).max(80),
|
|
47
|
+
version: semver,
|
|
48
|
+
publisher: publisherSchema,
|
|
49
|
+
// SPDX id — the FRONTEND's license (informational; core is AGPL-3.0).
|
|
50
|
+
license: z.string().min(1).max(80),
|
|
51
|
+
description: i18nMessageSchema,
|
|
52
|
+
categories: z.array(categorySchema).min(1),
|
|
53
|
+
})
|
|
54
|
+
.strict();
|
|
55
|
+
// ── §2.11 capabilities ───────────────────────────────────────────────────────
|
|
56
|
+
export const MANIFEST_CAPABILITIES = [
|
|
57
|
+
'hosted-only',
|
|
58
|
+
'offline-required',
|
|
59
|
+
'receipt-printer',
|
|
60
|
+
'barcode-scanner',
|
|
61
|
+
'payments',
|
|
62
|
+
'file-storage',
|
|
63
|
+
'email-delivery',
|
|
64
|
+
'realtime',
|
|
65
|
+
];
|
|
66
|
+
export const capabilitySchema = z.enum(MANIFEST_CAPABILITIES);
|
|
67
|
+
// ── §2.4 compatibility ───────────────────────────────────────────────────────
|
|
68
|
+
export const compatibilitySchema = z
|
|
69
|
+
.object({
|
|
70
|
+
minAdminiumVersion: semver,
|
|
71
|
+
maxAdminiumVersion: semver.optional(), // exclusive upper bound
|
|
72
|
+
requires: z.array(capabilitySchema).optional(),
|
|
73
|
+
})
|
|
74
|
+
.strict();
|
|
75
|
+
// ── §2.5 requiredSchema (create-or-map) ──────────────────────────────────────
|
|
76
|
+
/** Abstract column types the introspection engine emits (§2.5, research §15.2). */
|
|
77
|
+
export const COLUMN_TYPES = [
|
|
78
|
+
'id',
|
|
79
|
+
'text',
|
|
80
|
+
'int',
|
|
81
|
+
'bigint',
|
|
82
|
+
'decimal',
|
|
83
|
+
'money',
|
|
84
|
+
'float',
|
|
85
|
+
'bool',
|
|
86
|
+
'enum',
|
|
87
|
+
'json',
|
|
88
|
+
'date',
|
|
89
|
+
'timestamptz',
|
|
90
|
+
'uuid',
|
|
91
|
+
'fk',
|
|
92
|
+
'blob',
|
|
93
|
+
];
|
|
94
|
+
/** Optional semantic pre-seed so widgets auto-instantiate (§2.5). */
|
|
95
|
+
export const COLUMN_SEMANTICS = [
|
|
96
|
+
'name',
|
|
97
|
+
'money',
|
|
98
|
+
'image',
|
|
99
|
+
'email',
|
|
100
|
+
'avatar',
|
|
101
|
+
'geo-lat',
|
|
102
|
+
'geo-lng',
|
|
103
|
+
];
|
|
104
|
+
/** Structural role markers (§2.5). */
|
|
105
|
+
export const COLUMN_ROLES = ['pk', 'created_at', 'updated_at'];
|
|
106
|
+
export const requiredColumnSchema = z
|
|
107
|
+
.object({
|
|
108
|
+
ref: z.string().regex(/^[a-z][a-z0-9_]*$/, 'column ref must be a snake_case identifier'),
|
|
109
|
+
type: z.enum(COLUMN_TYPES),
|
|
110
|
+
semantic: z.enum(COLUMN_SEMANTICS).optional(),
|
|
111
|
+
role: z.enum(COLUMN_ROLES).optional(),
|
|
112
|
+
nullable: z.boolean().optional(),
|
|
113
|
+
// enum values when `type: 'enum'`; fk target ref when `type: 'fk'`.
|
|
114
|
+
enum: z.array(z.string().min(1)).optional(),
|
|
115
|
+
references: z.string().optional(),
|
|
116
|
+
})
|
|
117
|
+
.strict()
|
|
118
|
+
.refine((c) => c.type !== 'enum' || (c.enum !== undefined && c.enum.length > 0), {
|
|
119
|
+
message: 'an enum column must list its enum values',
|
|
120
|
+
path: ['enum'],
|
|
121
|
+
})
|
|
122
|
+
.refine((c) => c.type !== 'fk' || c.references !== undefined, {
|
|
123
|
+
message: 'a fk column must name its references target',
|
|
124
|
+
path: ['references'],
|
|
125
|
+
});
|
|
126
|
+
export const requiredTableSchema = z
|
|
127
|
+
.object({
|
|
128
|
+
ref: z.string().regex(/^[a-z][a-z0-9_]*$/, 'table ref must be a snake_case identifier'),
|
|
129
|
+
columns: z.array(requiredColumnSchema).min(1),
|
|
130
|
+
})
|
|
131
|
+
.strict()
|
|
132
|
+
.refine((t) => new Set(t.columns.map((c) => c.ref)).size === t.columns.length, { message: 'duplicate column ref in table', path: ['columns'] });
|
|
133
|
+
export const requiredSchemaSchema = z
|
|
134
|
+
.object({
|
|
135
|
+
tables: z.array(requiredTableSchema).min(1),
|
|
136
|
+
})
|
|
137
|
+
.strict()
|
|
138
|
+
.refine((s) => new Set(s.tables.map((t) => t.ref)).size === s.tables.length, {
|
|
139
|
+
message: 'duplicate table ref in requiredSchema',
|
|
140
|
+
path: ['tables'],
|
|
141
|
+
});
|
|
142
|
+
// ── §2.6 pages ───────────────────────────────────────────────────────────────
|
|
143
|
+
export const pageNavSchema = z
|
|
144
|
+
.object({
|
|
145
|
+
group: z.string().min(1).max(80),
|
|
146
|
+
icon: z.string().min(1).max(60),
|
|
147
|
+
order: z.number().int(),
|
|
148
|
+
})
|
|
149
|
+
.strict();
|
|
150
|
+
export const pageSchema = z
|
|
151
|
+
.object({
|
|
152
|
+
ref: z.string().regex(/^[a-z][a-z0-9-]*$/, 'page ref must be a kebab-case identifier'),
|
|
153
|
+
template: z.string().min(1).max(80),
|
|
154
|
+
title: i18nMessageSchema,
|
|
155
|
+
nav: pageNavSchema,
|
|
156
|
+
// page-local table ref → requiredSchema table ref (resolved at install).
|
|
157
|
+
bindings: z.record(z.string(), z.string()).optional(),
|
|
158
|
+
config: z.record(z.string(), z.unknown()).optional(),
|
|
159
|
+
})
|
|
160
|
+
.strict();
|
|
161
|
+
// ── §2.7 roles ───────────────────────────────────────────────────────────────
|
|
162
|
+
export const roleSchema = z
|
|
163
|
+
.object({
|
|
164
|
+
key: z.string().regex(/^[a-z][a-z0-9-]*$/, 'role key must be a kebab-case identifier'),
|
|
165
|
+
name: z.string().min(1).max(80),
|
|
166
|
+
cloneFrom: z.string().optional(),
|
|
167
|
+
// grant strings validated against the RBAC grammar at install time.
|
|
168
|
+
permissions: z.array(z.string().min(1)).optional(),
|
|
169
|
+
})
|
|
170
|
+
.strict();
|
|
171
|
+
// ── §2.8 settings ────────────────────────────────────────────────────────────
|
|
172
|
+
const settingBase = {
|
|
173
|
+
key: z.string().regex(/^[a-z][a-z0-9_]*$/, 'setting key must be snake_case'),
|
|
174
|
+
required: z.boolean().optional(),
|
|
175
|
+
secret: z.boolean().optional(),
|
|
176
|
+
label: i18nMessageSchema.optional(),
|
|
177
|
+
};
|
|
178
|
+
export const settingSchema = z.discriminatedUnion('type', [
|
|
179
|
+
z.object({ ...settingBase, type: z.literal('string'), default: z.string().optional() }).strict(),
|
|
180
|
+
z
|
|
181
|
+
.object({
|
|
182
|
+
...settingBase,
|
|
183
|
+
type: z.literal('number'),
|
|
184
|
+
default: z.number().optional(),
|
|
185
|
+
min: z.number().optional(),
|
|
186
|
+
max: z.number().optional(),
|
|
187
|
+
unit: z.string().max(20).optional(),
|
|
188
|
+
})
|
|
189
|
+
.strict(),
|
|
190
|
+
z.object({ ...settingBase, type: z.literal('boolean'), default: z.boolean().optional() }).strict(),
|
|
191
|
+
z
|
|
192
|
+
.object({
|
|
193
|
+
...settingBase,
|
|
194
|
+
type: z.literal('enum'),
|
|
195
|
+
enum: z.array(z.string().min(1)).min(1),
|
|
196
|
+
default: z.string().optional(),
|
|
197
|
+
})
|
|
198
|
+
.strict(),
|
|
199
|
+
z
|
|
200
|
+
.object({
|
|
201
|
+
...settingBase,
|
|
202
|
+
type: z.literal('file'),
|
|
203
|
+
accept: z.array(z.string().min(1)).optional(),
|
|
204
|
+
})
|
|
205
|
+
.strict(),
|
|
206
|
+
z.object({ ...settingBase, type: z.literal('json'), default: z.unknown().optional() }).strict(),
|
|
207
|
+
]);
|
|
208
|
+
// ── §2.9 seeds ───────────────────────────────────────────────────────────────
|
|
209
|
+
export const seedSchema = z
|
|
210
|
+
.object({
|
|
211
|
+
table: z.string().min(1),
|
|
212
|
+
// inline rows, or a reference to a bundled seeds/<file> dataset (§2.9).
|
|
213
|
+
rows: z.array(z.record(z.string(), z.unknown())).optional(),
|
|
214
|
+
file: z.string().min(1).optional(),
|
|
215
|
+
})
|
|
216
|
+
.strict()
|
|
217
|
+
.refine((s) => (s.rows === undefined) !== (s.file === undefined), {
|
|
218
|
+
message: 'a seed provides exactly one of `rows` or `file`',
|
|
219
|
+
});
|
|
220
|
+
// ── §2.10 widgets (optional custom bundles) ──────────────────────────────────
|
|
221
|
+
export const manifestWidgetSchema = z
|
|
222
|
+
.object({
|
|
223
|
+
id: z.string().min(1).max(80),
|
|
224
|
+
entry: z.string().min(1),
|
|
225
|
+
})
|
|
226
|
+
.strict();
|
|
227
|
+
// ── §2.12 frontend ───────────────────────────────────────────────────────────
|
|
228
|
+
export const FRONTEND_KINDS = ['spa', 'electron', 'none'];
|
|
229
|
+
export const frontendEnvVarSchema = z
|
|
230
|
+
.object({
|
|
231
|
+
required: z.boolean(),
|
|
232
|
+
example: z.string().optional(),
|
|
233
|
+
})
|
|
234
|
+
.strict();
|
|
235
|
+
export const frontendSchema = z
|
|
236
|
+
.object({
|
|
237
|
+
kind: z.enum(FRONTEND_KINDS),
|
|
238
|
+
entry: z.string().min(1).optional(),
|
|
239
|
+
env: z.record(z.string(), frontendEnvVarSchema).optional(),
|
|
240
|
+
})
|
|
241
|
+
.strict();
|
|
242
|
+
// ── the manifest envelope ─────────────────────────────────────────────────────
|
|
243
|
+
export const manifestSchema = z
|
|
244
|
+
.object({
|
|
245
|
+
manifestVersion: z.literal(MANIFEST_VERSION),
|
|
246
|
+
...identitySchema.shape,
|
|
247
|
+
compatibility: compatibilitySchema,
|
|
248
|
+
requiredSchema: requiredSchemaSchema,
|
|
249
|
+
pages: z.array(pageSchema).min(1),
|
|
250
|
+
roles: z.array(roleSchema).optional(),
|
|
251
|
+
settings: z.array(settingSchema).optional(),
|
|
252
|
+
seeds: z.array(seedSchema).optional(),
|
|
253
|
+
widgets: z.array(manifestWidgetSchema).optional(),
|
|
254
|
+
capabilities: z.array(capabilitySchema).optional(),
|
|
255
|
+
frontend: frontendSchema,
|
|
256
|
+
})
|
|
257
|
+
.strict()
|
|
258
|
+
// §2.11: hosted-only and offline-required are mutually exclusive.
|
|
259
|
+
.refine((m) => !((m.capabilities?.includes('hosted-only') ?? false) &&
|
|
260
|
+
(m.capabilities?.includes('offline-required') ?? false)), { message: 'hosted-only and offline-required are mutually exclusive', path: ['capabilities'] })
|
|
261
|
+
// maxAdminiumVersion (exclusive) must be strictly above the min.
|
|
262
|
+
.refine((m) => m.compatibility.maxAdminiumVersion === undefined ||
|
|
263
|
+
compareSemver(m.compatibility.maxAdminiumVersion, m.compatibility.minAdminiumVersion) > 0, { message: 'maxAdminiumVersion must be greater than minAdminiumVersion', path: ['compatibility'] });
|
|
264
|
+
/**
|
|
265
|
+
* Numeric semver compare on the release triple (pre-release/build ignored —
|
|
266
|
+
* enough for the compatibility-window and upgrade ordering checks). Returns
|
|
267
|
+
* <0, 0, >0. Exported for the installer's upgrade rule (§4.3).
|
|
268
|
+
*/
|
|
269
|
+
export function compareSemver(a, b) {
|
|
270
|
+
const triple = (v) => v
|
|
271
|
+
.split('+')[0]
|
|
272
|
+
.split('-')[0]
|
|
273
|
+
.split('.')
|
|
274
|
+
.map((n) => Number.parseInt(n, 10));
|
|
275
|
+
const [a1 = 0, a2 = 0, a3 = 0] = triple(a);
|
|
276
|
+
const [b1 = 0, b2 = 0, b3 = 0] = triple(b);
|
|
277
|
+
return a1 - b1 || a2 - b2 || a3 - b3;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation entry point (13-marketplace.md §2, §9). Layers the
|
|
3
|
+
* envelope schema with the v1 publisher policy: the installer rejects any
|
|
4
|
+
* `publisher.id` other than `adminium` unless the `third-party-publishers`
|
|
5
|
+
* feature flag is on (off in v1). Pure — safe in the browser storefront.
|
|
6
|
+
*/
|
|
7
|
+
import { type Manifest } from './schema.js';
|
|
8
|
+
export interface ManifestIssue {
|
|
9
|
+
/** Dotted path to the offending field, e.g. `publisher.id`. */
|
|
10
|
+
path: string;
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ValidateManifestOptions {
|
|
14
|
+
/**
|
|
15
|
+
* Allow a non-`adminium` publisher. Wired to the `third-party-publishers`
|
|
16
|
+
* feature flag (§9); OFF in v1, so third-party manifests are rejected.
|
|
17
|
+
*/
|
|
18
|
+
allowThirdPartyPublishers?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export type ValidateManifestResult = {
|
|
21
|
+
ok: true;
|
|
22
|
+
manifest: Manifest;
|
|
23
|
+
} | {
|
|
24
|
+
ok: false;
|
|
25
|
+
issues: ManifestIssue[];
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Validate an untrusted manifest document. Returns the typed manifest on
|
|
29
|
+
* success, or every issue found (schema + policy) on failure — never throws.
|
|
30
|
+
*/
|
|
31
|
+
export declare function validateManifest(input: unknown, opts?: ValidateManifestOptions): ValidateManifestResult;
|
|
32
|
+
/** Throwing variant for trusted callers (build tooling); use the safe form at runtime. */
|
|
33
|
+
export declare function parseManifest(input: unknown, opts?: ValidateManifestOptions): Manifest;
|
|
34
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAA4C,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEtF,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC;AAE3C;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,IAAI,GAAE,uBAA4B,GACjC,sBAAsB,CAwBxB;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,GAAE,uBAA4B,GAAG,QAAQ,CAO1F"}
|
package/dist/validate.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest validation entry point (13-marketplace.md §2, §9). Layers the
|
|
3
|
+
* envelope schema with the v1 publisher policy: the installer rejects any
|
|
4
|
+
* `publisher.id` other than `adminium` unless the `third-party-publishers`
|
|
5
|
+
* feature flag is on (off in v1). Pure — safe in the browser storefront.
|
|
6
|
+
*/
|
|
7
|
+
import { FIRST_PARTY_PUBLISHER_ID, manifestSchema } from './schema.js';
|
|
8
|
+
/**
|
|
9
|
+
* Validate an untrusted manifest document. Returns the typed manifest on
|
|
10
|
+
* success, or every issue found (schema + policy) on failure — never throws.
|
|
11
|
+
*/
|
|
12
|
+
export function validateManifest(input, opts = {}) {
|
|
13
|
+
const parsed = manifestSchema.safeParse(input);
|
|
14
|
+
if (!parsed.success) {
|
|
15
|
+
return {
|
|
16
|
+
ok: false,
|
|
17
|
+
issues: parsed.error.issues.map((issue) => ({
|
|
18
|
+
path: issue.path.map(String).join('.'),
|
|
19
|
+
message: issue.message,
|
|
20
|
+
})),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const manifest = parsed.data;
|
|
24
|
+
const issues = [];
|
|
25
|
+
if (!(opts.allowThirdPartyPublishers ?? false) && manifest.publisher.id !== FIRST_PARTY_PUBLISHER_ID) {
|
|
26
|
+
issues.push({
|
|
27
|
+
path: 'publisher.id',
|
|
28
|
+
message: `third-party publishers are not accepted in v1 (expected "${FIRST_PARTY_PUBLISHER_ID}")`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
if (issues.length > 0)
|
|
32
|
+
return { ok: false, issues };
|
|
33
|
+
return { ok: true, manifest };
|
|
34
|
+
}
|
|
35
|
+
/** Throwing variant for trusted callers (build tooling); use the safe form at runtime. */
|
|
36
|
+
export function parseManifest(input, opts = {}) {
|
|
37
|
+
const result = validateManifest(input, opts);
|
|
38
|
+
if (!result.ok) {
|
|
39
|
+
const summary = result.issues.map((i) => `${i.path}: ${i.message}`).join('; ');
|
|
40
|
+
throw new Error(`invalid manifest: ${summary}`);
|
|
41
|
+
}
|
|
42
|
+
return result.manifest;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAiB,MAAM,aAAa,CAAC;AAoBtF;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAAc,EACd,OAAgC,EAAE;IAElC,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBACtC,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IAC7B,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,IAAI,CAAC,CAAC,IAAI,CAAC,yBAAyB,IAAI,KAAK,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,wBAAwB,EAAE,CAAC;QACrG,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,4DAA4D,wBAAwB,IAAI;SAClG,CAAC,CAAC;IACL,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAChC,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,KAAc,EAAE,OAAgC,EAAE;IAC9E,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/E,MAAM,IAAI,KAAK,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adminiumjs/manifest",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "AGPL-3.0-only",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
"default": "./dist/index.js"
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"zod": "^4.4.3"
|
|
24
|
+
},
|
|
22
25
|
"files": [
|
|
23
26
|
"dist"
|
|
24
27
|
]
|