@aphexcms/cms-core 0.1.16 → 0.2.1
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/api/client.d.ts.map +1 -1
- package/dist/api/client.js +7 -1
- package/dist/api/types.d.ts +2 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/cli/generate-types.js +62 -17
- package/dist/cli/index.js +1 -1
- package/dist/client/index.d.ts +0 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +0 -1
- package/dist/components/AdminApp.svelte +278 -45
- package/dist/components/AdminApp.svelte.d.ts +2 -0
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/DocumentEditor.svelte +60 -13
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/ObjectModal.svelte +15 -4
- package/dist/components/admin/ObjectModal.svelte.d.ts +1 -0
- package/dist/components/admin/ObjectModal.svelte.d.ts.map +1 -1
- package/dist/components/admin/SchemaField.svelte +64 -5
- package/dist/components/admin/SchemaField.svelte.d.ts +1 -0
- package/dist/components/admin/SchemaField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +402 -111
- package/dist/components/admin/fields/ArrayField.svelte.d.ts +1 -0
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/DateField.svelte +145 -0
- package/dist/components/admin/fields/DateField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/DateField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/DateTimeField.svelte +225 -0
- package/dist/components/admin/fields/DateTimeField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/DateTimeField.svelte.d.ts.map +1 -0
- package/dist/components/admin/fields/ImageField.svelte +221 -110
- package/dist/components/admin/fields/ImageField.svelte.d.ts +2 -0
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +1 -1
- package/dist/components/admin/fields/SlugField.svelte +21 -13
- package/dist/components/admin/fields/SlugField.svelte.d.ts +2 -2
- package/dist/components/admin/fields/SlugField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/StringField.svelte +156 -12
- package/dist/components/admin/fields/StringField.svelte.d.ts +3 -2
- package/dist/components/admin/fields/StringField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/URLField.svelte +41 -0
- package/dist/components/admin/fields/URLField.svelte.d.ts +14 -0
- package/dist/components/admin/fields/URLField.svelte.d.ts.map +1 -0
- package/dist/components/index.d.ts +0 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +0 -1
- package/dist/db/interfaces/asset.d.ts.map +1 -1
- package/dist/db/interfaces/document.d.ts +0 -2
- package/dist/db/interfaces/document.d.ts.map +1 -1
- package/dist/db/interfaces/index.d.ts +2 -1
- package/dist/db/interfaces/index.d.ts.map +1 -1
- package/dist/db/interfaces/user.d.ts +2 -0
- package/dist/db/interfaces/user.d.ts.map +1 -1
- package/dist/db/utils/reference-resolver.js +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +3 -0
- package/dist/field-validation/date-utils.d.ts +30 -0
- package/dist/field-validation/date-utils.d.ts.map +1 -0
- package/dist/field-validation/date-utils.js +147 -0
- package/dist/field-validation/rule.d.ts +4 -0
- package/dist/field-validation/rule.d.ts.map +1 -1
- package/dist/field-validation/rule.js +170 -4
- package/dist/field-validation/utils.d.ts +7 -3
- package/dist/field-validation/utils.d.ts.map +1 -1
- package/dist/field-validation/utils.js +130 -38
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +38 -21
- package/dist/lib/field-validation/date-utils.js +147 -0
- package/dist/lib/field-validation/rule.js +170 -4
- package/dist/lib/field-validation/utils.js +130 -38
- package/dist/local-api/collection-api.d.ts +16 -4
- package/dist/local-api/collection-api.d.ts.map +1 -1
- package/dist/local-api/collection-api.js +51 -17
- package/dist/local-api/index.d.ts +1 -1
- package/dist/local-api/index.d.ts.map +1 -1
- package/dist/routes/assets-cdn.d.ts.map +1 -1
- package/dist/routes/assets-cdn.js +14 -7
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +6 -1
- package/dist/routes/documents-by-id.d.ts.map +1 -1
- package/dist/routes/documents-by-id.js +18 -7
- package/dist/routes/documents-publish.js +2 -2
- package/dist/routes/documents-query.d.ts +3 -1
- package/dist/routes/documents-query.d.ts.map +1 -1
- package/dist/routes/documents-query.js +6 -2
- package/dist/routes/documents.d.ts.map +1 -1
- package/dist/routes/documents.js +20 -4
- package/dist/routes/index.d.ts +1 -0
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -0
- package/dist/routes/user-preferences.d.ts +4 -0
- package/dist/routes/user-preferences.d.ts.map +1 -0
- package/dist/routes/user-preferences.js +77 -0
- package/dist/schema-utils/utils.d.ts +4 -0
- package/dist/schema-utils/utils.d.ts.map +1 -1
- package/dist/schema-utils/utils.js +23 -2
- package/dist/schema-utils/validator.d.ts +4 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +120 -0
- package/dist/types/filters.d.ts +13 -0
- package/dist/types/filters.d.ts.map +1 -1
- package/dist/types/organization.d.ts +3 -0
- package/dist/types/organization.d.ts.map +1 -1
- package/dist/types/schemas.d.ts +67 -7
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/default-orderings.d.ts +10 -0
- package/dist/utils/default-orderings.d.ts.map +1 -0
- package/dist/utils/default-orderings.js +63 -0
- package/dist/utils/field-defaults.d.ts +8 -0
- package/dist/utils/field-defaults.d.ts.map +1 -0
- package/dist/utils/field-defaults.js +20 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/initial-value-helpers.d.ts +50 -0
- package/dist/utils/initial-value-helpers.d.ts.map +1 -0
- package/dist/utils/initial-value-helpers.js +70 -0
- package/package.json +6 -4
- package/dist/components/admin/DocumentTypesList.svelte +0 -97
- package/dist/components/admin/DocumentTypesList.svelte.d.ts +0 -14
- package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +0 -1
|
@@ -124,7 +124,7 @@ export class CollectionAPI {
|
|
|
124
124
|
*
|
|
125
125
|
* @example
|
|
126
126
|
* ```typescript
|
|
127
|
-
* const
|
|
127
|
+
* const result = await api.collections.pages.create(
|
|
128
128
|
* { organizationId: 'org_123', user },
|
|
129
129
|
* {
|
|
130
130
|
* title: 'New Page',
|
|
@@ -132,15 +132,18 @@ export class CollectionAPI {
|
|
|
132
132
|
* content: []
|
|
133
133
|
* }
|
|
134
134
|
* );
|
|
135
|
+
* // result.document - the created document
|
|
136
|
+
* // result.validation - validation results
|
|
135
137
|
* ```
|
|
136
138
|
*/
|
|
137
139
|
async create(context, data, options) {
|
|
138
140
|
// Permission check (unless overrideAccess)
|
|
139
141
|
await this.permissions.canWrite(context, this.collectionName);
|
|
140
|
-
// Validate data
|
|
142
|
+
// Validate and normalize data (dates converted to ISO)
|
|
143
|
+
const validationResult = await validateDocumentData(this._schema, data, data);
|
|
141
144
|
if (options?.publish) {
|
|
142
145
|
await this.permissions.canPublish(context, this.collectionName);
|
|
143
|
-
|
|
146
|
+
// Block publish if validation fails
|
|
144
147
|
if (!validationResult.isValid) {
|
|
145
148
|
const errorMessage = validationResult.errors
|
|
146
149
|
.map((e) => `${e.field}: ${e.errors.join(', ')}`)
|
|
@@ -148,48 +151,73 @@ export class CollectionAPI {
|
|
|
148
151
|
throw new Error(`Cannot publish: validation errors - ${errorMessage}`);
|
|
149
152
|
}
|
|
150
153
|
}
|
|
151
|
-
// Create document with
|
|
154
|
+
// Create document with normalized data (dates in ISO format)
|
|
152
155
|
const document = await this.databaseAdapter.createDocument({
|
|
153
156
|
organizationId: context.organizationId,
|
|
154
157
|
type: this.collectionName,
|
|
155
|
-
draftData:
|
|
158
|
+
draftData: validationResult.normalizedData,
|
|
156
159
|
createdBy: context.user?.id
|
|
157
160
|
});
|
|
158
161
|
// Publish immediately if requested (validation already done above)
|
|
159
162
|
if (options?.publish) {
|
|
160
163
|
const published = await this.databaseAdapter.publishDoc(context.organizationId, document.id);
|
|
161
164
|
if (published) {
|
|
162
|
-
return
|
|
165
|
+
return {
|
|
166
|
+
document: transformDocument(published, 'published'),
|
|
167
|
+
validation: validationResult
|
|
168
|
+
};
|
|
163
169
|
}
|
|
164
170
|
}
|
|
165
|
-
return
|
|
171
|
+
return {
|
|
172
|
+
document: transformDocument(document, 'draft'),
|
|
173
|
+
validation: validationResult
|
|
174
|
+
};
|
|
166
175
|
}
|
|
167
176
|
/**
|
|
168
177
|
* Update an existing document
|
|
169
178
|
*
|
|
170
179
|
* @example
|
|
171
180
|
* ```typescript
|
|
172
|
-
* const
|
|
181
|
+
* const result = await api.collections.pages.update(
|
|
173
182
|
* { organizationId: 'org_123', user },
|
|
174
183
|
* 'doc_123',
|
|
175
184
|
* { title: 'Updated Title' },
|
|
176
185
|
* { publish: true }
|
|
177
186
|
* );
|
|
187
|
+
* // result.document - the updated document
|
|
188
|
+
* // result.validation - validation results
|
|
178
189
|
* ```
|
|
179
190
|
*/
|
|
180
191
|
async update(context, id, data, options) {
|
|
181
192
|
// Permission check (unless overrideAccess)
|
|
182
193
|
await this.permissions.canWrite(context, this.collectionName);
|
|
183
|
-
//
|
|
184
|
-
const
|
|
194
|
+
// Get existing document to merge with updates
|
|
195
|
+
const existingDoc = await this.databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
196
|
+
if (!existingDoc) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
// Merge existing data with updates, but only keep fields defined in schema
|
|
200
|
+
// This prevents orphaned fields from persisting when schema changes
|
|
201
|
+
const schemaFieldNames = new Set(this._schema.fields.map((f) => f.name));
|
|
202
|
+
const cleanedExisting = {};
|
|
203
|
+
// Only copy fields from existing doc that are still in the schema
|
|
204
|
+
for (const [key, value] of Object.entries(existingDoc.draftData || {})) {
|
|
205
|
+
if (schemaFieldNames.has(key)) {
|
|
206
|
+
cleanedExisting[key] = value;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// Merge cleaned existing data with new updates
|
|
210
|
+
const mergedData = { ...cleanedExisting, ...data };
|
|
211
|
+
// Validate and normalize the merged data
|
|
212
|
+
const validationResult = await validateDocumentData(this._schema, mergedData, mergedData);
|
|
213
|
+
// Update draft with normalized data (dates in ISO format)
|
|
214
|
+
const document = await this.databaseAdapter.updateDocDraft(context.organizationId, id, validationResult.normalizedData, context.user?.id);
|
|
185
215
|
if (!document) {
|
|
186
216
|
return null;
|
|
187
217
|
}
|
|
188
|
-
// Validate and publish immediately if requested
|
|
189
218
|
if (options?.publish) {
|
|
190
219
|
await this.permissions.canPublish(context, this.collectionName);
|
|
191
|
-
//
|
|
192
|
-
const validationResult = await validateDocumentData(this._schema, document.draftData, document.draftData);
|
|
220
|
+
// Block publish if validation fails
|
|
193
221
|
if (!validationResult.isValid) {
|
|
194
222
|
const errorMessage = validationResult.errors
|
|
195
223
|
.map((e) => `${e.field}: ${e.errors.join(', ')}`)
|
|
@@ -198,10 +226,16 @@ export class CollectionAPI {
|
|
|
198
226
|
}
|
|
199
227
|
const published = await this.databaseAdapter.publishDoc(context.organizationId, document.id);
|
|
200
228
|
if (published) {
|
|
201
|
-
return
|
|
229
|
+
return {
|
|
230
|
+
document: transformDocument(published, 'published'),
|
|
231
|
+
validation: validationResult
|
|
232
|
+
};
|
|
202
233
|
}
|
|
203
234
|
}
|
|
204
|
-
return
|
|
235
|
+
return {
|
|
236
|
+
document: transformDocument(document, 'draft'),
|
|
237
|
+
validation: validationResult
|
|
238
|
+
};
|
|
205
239
|
}
|
|
206
240
|
/**
|
|
207
241
|
* Delete a document
|
|
@@ -234,11 +268,11 @@ export class CollectionAPI {
|
|
|
234
268
|
// Permission check (unless overrideAccess)
|
|
235
269
|
await this.permissions.canPublish(context, this.collectionName);
|
|
236
270
|
// Get the document to access draft data for validation
|
|
237
|
-
const document = await this.databaseAdapter.
|
|
271
|
+
const document = await this.databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
238
272
|
if (!document || !document.draftData) {
|
|
239
273
|
throw new Error('Document not found or has no draft content to publish');
|
|
240
274
|
}
|
|
241
|
-
// Validate draft data
|
|
275
|
+
// Validate draft data (dates already in ISO, will be converted for validation)
|
|
242
276
|
const validationResult = await validateDocumentData(this._schema, document.draftData, document.draftData);
|
|
243
277
|
if (!validationResult.isValid) {
|
|
244
278
|
const errorMessage = validationResult.errors
|
|
@@ -101,7 +101,7 @@ export declare function createLocalAPI(config: CMSConfig, userAdapter: DatabaseA
|
|
|
101
101
|
* ```
|
|
102
102
|
*/
|
|
103
103
|
export declare function getLocalAPI(): LocalAPI;
|
|
104
|
-
export { CollectionAPI } from './collection-api.js';
|
|
104
|
+
export { CollectionAPI, type DocumentResult } from './collection-api.js';
|
|
105
105
|
export { PermissionChecker, PermissionError } from './permissions.js';
|
|
106
106
|
export type { LocalAPIContext, CreateOptions, UpdateOptions } from './types.js';
|
|
107
107
|
export { authToContext, requireAuth, systemContext } from './auth-helpers.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAE3B,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;CAGjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,QAAQ;IAQnB,OAAO,CAAC,MAAM;IAPR,WAAW,EAAE,WAAW,CAAM;IACrC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,OAAO,CAA0B;gBAGhC,MAAM,EAAE,SAAS,EACzB,WAAW,EAAE,eAAe,EAC5B,aAAa,CAAC,EAAE,eAAe;IAmBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/local-api/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAIjD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAE3B,CAAC,cAAc,EAAE,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;CAGjD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,QAAQ;IAQnB,OAAO,CAAC,MAAM;IAPR,WAAW,EAAE,WAAW,CAAM;IACrC,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,OAAO,CAA0B;gBAGhC,MAAM,EAAE,SAAS,EACzB,WAAW,EAAE,eAAe,EAC5B,aAAa,CAAC,EAAE,eAAe;IAmBhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgC7B;;;OAGG;IACH,OAAO,CAAC,UAAU;IAOlB;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIpC;;OAEG;IACH,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;CAGzD;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAC7B,MAAM,EAAE,SAAS,EACjB,WAAW,EAAE,eAAe,EAC5B,aAAa,CAAC,EAAE,eAAe,GAC7B,QAAQ,CAGV;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAKtC;AAGD,OAAO,EAAE,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACnE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets-cdn.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-cdn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"assets-cdn.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets-cdn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,GAAG,EAAE,cAqMjB,CAAC"}
|
|
@@ -97,14 +97,21 @@ export const GET = async ({ params, locals, setHeaders, request }) => {
|
|
|
97
97
|
console.warn('[Asset CDN] Private asset accessed without auth - DENIED');
|
|
98
98
|
return new Response('Unauthorized - This asset is private', { status: 401 });
|
|
99
99
|
}
|
|
100
|
-
// If asset is private, verify org
|
|
101
|
-
|
|
102
|
-
console.warn('[Asset CDN] Org mismatch for private asset - FORBIDDEN');
|
|
103
|
-
return new Response('Forbidden', { status: 403 });
|
|
104
|
-
}
|
|
105
|
-
// Log the decision
|
|
100
|
+
// If asset is private, verify user has access to the asset's org
|
|
101
|
+
// This includes exact match OR parent org accessing child org asset (hierarchy)
|
|
106
102
|
if (isPrivate && organizationId) {
|
|
107
|
-
|
|
103
|
+
let hasAccess = organizationId === asset.organizationId; // Same org
|
|
104
|
+
// If not same org, check if asset's org is a child of user's org (hierarchy)
|
|
105
|
+
if (!hasAccess && databaseAdapter.getChildOrganizations) {
|
|
106
|
+
const childOrgs = await databaseAdapter.getChildOrganizations(organizationId);
|
|
107
|
+
hasAccess = childOrgs.includes(asset.organizationId);
|
|
108
|
+
console.log(`[Asset CDN] Checking hierarchy: user org ${organizationId} has ${childOrgs.length} children, asset org ${asset.organizationId} is child? ${hasAccess}`);
|
|
109
|
+
}
|
|
110
|
+
if (!hasAccess) {
|
|
111
|
+
console.warn(`[Asset CDN] Org ${organizationId} cannot access asset from org ${asset.organizationId} - FORBIDDEN`);
|
|
112
|
+
return new Response('Forbidden', { status: 403 });
|
|
113
|
+
}
|
|
114
|
+
console.log(`[Asset CDN] Private asset access ALLOWED - user org ${organizationId} has access to asset org ${asset.organizationId}`);
|
|
108
115
|
}
|
|
109
116
|
else if (!isPrivate) {
|
|
110
117
|
console.log('[Asset CDN] Public asset access ALLOWED');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../src/lib/routes/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,IAAI,EAAE,cAuElB,CAAC;AAEF,eAAO,MAAM,GAAG,EAAE,cA4CjB,CAAC"}
|
package/dist/routes/assets.js
CHANGED
|
@@ -23,8 +23,12 @@ export const POST = async ({ request, locals }) => {
|
|
|
23
23
|
// Get field metadata for privacy checking
|
|
24
24
|
const schemaType = formData.get('schemaType') || undefined;
|
|
25
25
|
const fieldPath = formData.get('fieldPath') || undefined;
|
|
26
|
+
// Get target organization (document's org takes precedence)
|
|
27
|
+
// This allows assets to belong to the document's org, not the uploader's org
|
|
28
|
+
const targetOrganizationId = formData.get('organizationId') || auth.organizationId;
|
|
26
29
|
// Create asset upload data
|
|
27
30
|
const uploadData = {
|
|
31
|
+
organizationId: targetOrganizationId, // Asset belongs to document's org
|
|
28
32
|
buffer,
|
|
29
33
|
originalFilename: file.name,
|
|
30
34
|
mimeType: file.type,
|
|
@@ -40,7 +44,8 @@ export const POST = async ({ request, locals }) => {
|
|
|
40
44
|
}
|
|
41
45
|
};
|
|
42
46
|
// Upload asset using the service
|
|
43
|
-
|
|
47
|
+
// The adapter will validate hierarchy access via withOrgContext
|
|
48
|
+
const asset = await assetService.uploadAsset(targetOrganizationId, uploadData);
|
|
44
49
|
return json({
|
|
45
50
|
success: true,
|
|
46
51
|
data: asset
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"documents-by-id.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-by-id.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAMpD,eAAO,MAAM,GAAG,EAAE,cAuEjB,CAAC;AAIF,eAAO,MAAM,GAAG,EAAE,cAkFjB,CAAC;AAGF,eAAO,MAAM,MAAM,EAAE,cA+DpB,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { json } from '@sveltejs/kit';
|
|
|
3
3
|
import { authToContext } from '../local-api/auth-helpers.js';
|
|
4
4
|
import { PermissionError } from '../local-api/permissions.js';
|
|
5
5
|
// GET /api/documents/[id] - Get document by ID
|
|
6
|
+
// TODO ENABLE CHILDREN ORG ACCESS BY DEFAULT - BECAUSE IF A PARENT ORG IS TRYING TO ACCESS A CHILD ORG. It should already have access to said id.
|
|
6
7
|
export const GET = async ({ params, url, locals }) => {
|
|
7
8
|
try {
|
|
8
9
|
const { localAPI, databaseAdapter } = locals.aphexCMS;
|
|
@@ -16,7 +17,7 @@ export const GET = async ({ params, url, locals }) => {
|
|
|
16
17
|
const depth = depthParam ? Math.max(0, Math.min(parseInt(depthParam), 5)) : 0;
|
|
17
18
|
const perspective = url.searchParams.get('perspective') || 'draft';
|
|
18
19
|
// First, fetch document to get its type (need this for collection-specific API)
|
|
19
|
-
const rawDoc = await databaseAdapter.
|
|
20
|
+
const rawDoc = await databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
20
21
|
if (!rawDoc) {
|
|
21
22
|
return json({ success: false, error: 'Document not found' }, { status: 404 });
|
|
22
23
|
}
|
|
@@ -59,6 +60,7 @@ export const GET = async ({ params, url, locals }) => {
|
|
|
59
60
|
}
|
|
60
61
|
};
|
|
61
62
|
// PUT /api/documents/[id] - Update document
|
|
63
|
+
// TODO ENABLE CHILDREN ORG ACCESS BY DEFAULT - BECAUSE IF A PARENT ORG IS TRYING TO ACCESS A CHILD ORG. It should already have access to said id.
|
|
62
64
|
export const PUT = async ({ params, request, locals }) => {
|
|
63
65
|
try {
|
|
64
66
|
const { localAPI, databaseAdapter } = locals.aphexCMS;
|
|
@@ -71,7 +73,7 @@ export const PUT = async ({ params, request, locals }) => {
|
|
|
71
73
|
const documentData = body.draftData || body.data;
|
|
72
74
|
const shouldPublish = body.publish || false;
|
|
73
75
|
// Fetch document to get its type
|
|
74
|
-
const rawDoc = await databaseAdapter.
|
|
76
|
+
const rawDoc = await databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
75
77
|
if (!rawDoc) {
|
|
76
78
|
return json({ success: false, error: 'Document not found' }, { status: 404 });
|
|
77
79
|
}
|
|
@@ -84,16 +86,17 @@ export const PUT = async ({ params, request, locals }) => {
|
|
|
84
86
|
message: `Collection '${rawDoc.type}' not found`
|
|
85
87
|
}, { status: 400 });
|
|
86
88
|
}
|
|
87
|
-
// Update via LocalAPI (permission checks happen inside)
|
|
88
|
-
const
|
|
89
|
+
// Update via LocalAPI (permission checks and validation happen inside)
|
|
90
|
+
const result = await collection.update(context, id, documentData, {
|
|
89
91
|
publish: shouldPublish
|
|
90
92
|
});
|
|
91
|
-
if (!
|
|
93
|
+
if (!result) {
|
|
92
94
|
return json({ success: false, error: 'Document not found' }, { status: 404 });
|
|
93
95
|
}
|
|
94
96
|
return json({
|
|
95
97
|
success: true,
|
|
96
|
-
data:
|
|
98
|
+
data: result.document,
|
|
99
|
+
validation: result.validation
|
|
97
100
|
});
|
|
98
101
|
}
|
|
99
102
|
catch (error) {
|
|
@@ -105,6 +108,14 @@ export const PUT = async ({ params, request, locals }) => {
|
|
|
105
108
|
message: error.message
|
|
106
109
|
}, { status: 403 });
|
|
107
110
|
}
|
|
111
|
+
// Validation errors from publish attempts
|
|
112
|
+
if (error instanceof Error && error.message.includes('validation errors')) {
|
|
113
|
+
return json({
|
|
114
|
+
success: false,
|
|
115
|
+
error: 'Validation failed',
|
|
116
|
+
message: error.message
|
|
117
|
+
}, { status: 400 });
|
|
118
|
+
}
|
|
108
119
|
return json({
|
|
109
120
|
success: false,
|
|
110
121
|
error: 'Failed to update document',
|
|
@@ -122,7 +133,7 @@ export const DELETE = async ({ params, locals }) => {
|
|
|
122
133
|
return json({ success: false, error: 'Document ID is required' }, { status: 400 });
|
|
123
134
|
}
|
|
124
135
|
// Fetch document to get its type
|
|
125
|
-
const rawDoc = await databaseAdapter.
|
|
136
|
+
const rawDoc = await databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
126
137
|
if (!rawDoc) {
|
|
127
138
|
return json({ success: false, error: 'Document not found' }, { status: 404 });
|
|
128
139
|
}
|
|
@@ -16,7 +16,7 @@ export const POST = async ({ params, locals }) => {
|
|
|
16
16
|
}, { status: 400 });
|
|
17
17
|
}
|
|
18
18
|
// Fetch document to get its type
|
|
19
|
-
const rawDoc = await databaseAdapter.
|
|
19
|
+
const rawDoc = await databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
20
20
|
if (!rawDoc) {
|
|
21
21
|
return json({
|
|
22
22
|
success: false,
|
|
@@ -86,7 +86,7 @@ export const DELETE = async ({ params, locals }) => {
|
|
|
86
86
|
}, { status: 400 });
|
|
87
87
|
}
|
|
88
88
|
// Fetch document to get its type
|
|
89
|
-
const rawDoc = await databaseAdapter.
|
|
89
|
+
const rawDoc = await databaseAdapter.findByDocIdAdvanced(context.organizationId, id);
|
|
90
90
|
if (!rawDoc) {
|
|
91
91
|
return json({
|
|
92
92
|
success: false,
|
|
@@ -17,7 +17,9 @@ import type { RequestHandler } from '@sveltejs/kit';
|
|
|
17
17
|
* "page": 1,
|
|
18
18
|
* "sort": ["-publishedAt", "title"],
|
|
19
19
|
* "depth": 1,
|
|
20
|
-
* "perspective": "published"
|
|
20
|
+
* "perspective": "published",
|
|
21
|
+
* "filterOrganizationIds": ["org_child1", "org_child2"],
|
|
22
|
+
* "includeChildOrganizations": false
|
|
21
23
|
* }
|
|
22
24
|
*/
|
|
23
25
|
export declare const POST: RequestHandler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AASpD
|
|
1
|
+
{"version":3,"file":"documents-query.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents-query.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AASpD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,IAAI,EAAE,cAuFlB,CAAC"}
|
|
@@ -23,7 +23,9 @@ const DEFAULT_PAGE = 1;
|
|
|
23
23
|
* "page": 1,
|
|
24
24
|
* "sort": ["-publishedAt", "title"],
|
|
25
25
|
* "depth": 1,
|
|
26
|
-
* "perspective": "published"
|
|
26
|
+
* "perspective": "published",
|
|
27
|
+
* "filterOrganizationIds": ["org_child1", "org_child2"],
|
|
28
|
+
* "includeChildOrganizations": false
|
|
27
29
|
* }
|
|
28
30
|
*/
|
|
29
31
|
export const POST = async ({ request, locals }) => {
|
|
@@ -60,7 +62,9 @@ export const POST = async ({ request, locals }) => {
|
|
|
60
62
|
sort: body.sort,
|
|
61
63
|
depth: body.depth !== undefined ? Math.max(0, Math.min(body.depth, 5)) : 0,
|
|
62
64
|
select: body.select,
|
|
63
|
-
perspective: body.perspective || 'draft'
|
|
65
|
+
perspective: body.perspective || 'draft',
|
|
66
|
+
includeChildOrganizations: body.includeChildOrganizations,
|
|
67
|
+
filterOrganizationIds: body.filterOrganizationIds
|
|
64
68
|
};
|
|
65
69
|
// Query via LocalAPI
|
|
66
70
|
const result = await localAPI.collections[documentType].find(context, findOptions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AASpD,eAAO,MAAM,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/lib/routes/documents.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AASpD,eAAO,MAAM,GAAG,EAAE,cAwGjB,CAAC;AAGF,eAAO,MAAM,IAAI,EAAE,cAmFlB,CAAC"}
|
package/dist/routes/documents.js
CHANGED
|
@@ -18,6 +18,11 @@ export const GET = async ({ url, locals }) => {
|
|
|
18
18
|
const depthParam = url.searchParams.get('depth');
|
|
19
19
|
const sortParam = url.searchParams.get('sort');
|
|
20
20
|
const perspective = url.searchParams.get('perspective') || 'draft';
|
|
21
|
+
const includeChildOrganizations = url.searchParams.get('includeChildOrganizations') === 'true';
|
|
22
|
+
const filterOrganizationIds = url.searchParams
|
|
23
|
+
.get('filterOrganizationIds')
|
|
24
|
+
?.split(',')
|
|
25
|
+
.filter(Boolean);
|
|
21
26
|
// Parse pagination
|
|
22
27
|
const page = pageParam ? Math.max(1, parseInt(pageParam)) : DEFAULT_PAGE;
|
|
23
28
|
const pageSize = pageSizeParam ? parseInt(pageSizeParam) : DEFAULT_PAGE_SIZE;
|
|
@@ -52,7 +57,9 @@ export const GET = async ({ url, locals }) => {
|
|
|
52
57
|
offset: offset,
|
|
53
58
|
depth: depth,
|
|
54
59
|
sort: sortParam || undefined,
|
|
55
|
-
perspective
|
|
60
|
+
perspective,
|
|
61
|
+
includeChildOrganizations,
|
|
62
|
+
filterOrganizationIds
|
|
56
63
|
});
|
|
57
64
|
return json({
|
|
58
65
|
success: true,
|
|
@@ -109,13 +116,14 @@ export const POST = async ({ request, locals }) => {
|
|
|
109
116
|
message: `Collection '${documentType}' not found. Available: ${localAPI.getCollectionNames().join(', ')}`
|
|
110
117
|
}, { status: 400 });
|
|
111
118
|
}
|
|
112
|
-
// Create via LocalAPI (permission checks happen inside)
|
|
113
|
-
const
|
|
119
|
+
// Create via LocalAPI (permission checks and validation happen inside)
|
|
120
|
+
const result = await collection.create(context, documentData, {
|
|
114
121
|
publish: shouldPublish
|
|
115
122
|
});
|
|
116
123
|
return json({
|
|
117
124
|
success: true,
|
|
118
|
-
data:
|
|
125
|
+
data: result.document,
|
|
126
|
+
validation: result.validation
|
|
119
127
|
}, { status: 201 });
|
|
120
128
|
}
|
|
121
129
|
catch (error) {
|
|
@@ -127,6 +135,14 @@ export const POST = async ({ request, locals }) => {
|
|
|
127
135
|
message: error.message
|
|
128
136
|
}, { status: 403 });
|
|
129
137
|
}
|
|
138
|
+
// Validation errors from publish attempts
|
|
139
|
+
if (error instanceof Error && error.message.includes('validation errors')) {
|
|
140
|
+
return json({
|
|
141
|
+
success: false,
|
|
142
|
+
error: 'Validation failed',
|
|
143
|
+
message: error.message
|
|
144
|
+
}, { status: 400 });
|
|
145
|
+
}
|
|
130
146
|
return json({
|
|
131
147
|
success: false,
|
|
132
148
|
error: 'Failed to create document',
|
package/dist/routes/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export * as documentsPublish from './documents-publish.js';
|
|
|
5
5
|
export * as assets from './assets.js';
|
|
6
6
|
export * as schemas from './schemas.js';
|
|
7
7
|
export * as schemasByType from './schemas-by-type.js';
|
|
8
|
+
export * as userPreferences from './user-preferences.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/routes/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAGnC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,aAAa,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/routes/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,aAAa,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,gBAAgB,MAAM,qBAAqB,CAAC;AAGxD,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AAGnC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,aAAa,MAAM,mBAAmB,CAAC;AAGnD,OAAO,KAAK,eAAe,MAAM,oBAAoB,CAAC"}
|
package/dist/routes/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-preferences.d.ts","sourceRoot":"","sources":["../../src/lib/routes/user-preferences.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAIpD,eAAO,MAAM,GAAG,EAAE,cAiCjB,CAAC;AAGF,eAAO,MAAM,KAAK,EAAE,cAkEnB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Aphex CMS User Preferences API Handler
|
|
2
|
+
import { json } from '@sveltejs/kit';
|
|
3
|
+
// GET /api/user/preferences - Get user preferences
|
|
4
|
+
export const GET = async ({ locals }) => {
|
|
5
|
+
try {
|
|
6
|
+
const { databaseAdapter } = locals.aphexCMS;
|
|
7
|
+
const auth = locals.auth;
|
|
8
|
+
if (!auth || auth.type !== 'session') {
|
|
9
|
+
return json({
|
|
10
|
+
success: false,
|
|
11
|
+
error: 'Unauthorized',
|
|
12
|
+
message: 'Session authentication required'
|
|
13
|
+
}, { status: 401 });
|
|
14
|
+
}
|
|
15
|
+
const userProfile = await databaseAdapter.findUserProfileById(auth.user.id);
|
|
16
|
+
return json({
|
|
17
|
+
success: true,
|
|
18
|
+
data: userProfile?.preferences || {}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
console.error('Failed to get user preferences:', error);
|
|
23
|
+
return json({
|
|
24
|
+
success: false,
|
|
25
|
+
error: 'Failed to get user preferences',
|
|
26
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
27
|
+
}, { status: 500 });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
// PATCH /api/user/preferences - Update user preferences (partial update)
|
|
31
|
+
export const PATCH = async ({ request, locals }) => {
|
|
32
|
+
try {
|
|
33
|
+
const { databaseAdapter } = locals.aphexCMS;
|
|
34
|
+
const auth = locals.auth;
|
|
35
|
+
if (!auth || auth.type !== 'session') {
|
|
36
|
+
return json({
|
|
37
|
+
success: false,
|
|
38
|
+
error: 'Unauthorized',
|
|
39
|
+
message: 'Session authentication required'
|
|
40
|
+
}, { status: 401 });
|
|
41
|
+
}
|
|
42
|
+
const body = (await request.json());
|
|
43
|
+
// Validate the preferences object
|
|
44
|
+
if (typeof body !== 'object' || body === null) {
|
|
45
|
+
return json({
|
|
46
|
+
success: false,
|
|
47
|
+
error: 'Invalid request body',
|
|
48
|
+
message: 'Expected an object with preference values'
|
|
49
|
+
}, { status: 400 });
|
|
50
|
+
}
|
|
51
|
+
// Validate individual preference types
|
|
52
|
+
if (body.includeChildOrganizations !== undefined &&
|
|
53
|
+
typeof body.includeChildOrganizations !== 'boolean') {
|
|
54
|
+
return json({
|
|
55
|
+
success: false,
|
|
56
|
+
error: 'Invalid preference value',
|
|
57
|
+
message: 'includeChildOrganizations must be a boolean'
|
|
58
|
+
}, { status: 400 });
|
|
59
|
+
}
|
|
60
|
+
// Update preferences
|
|
61
|
+
await databaseAdapter.updateUserPreferences(auth.user.id, body);
|
|
62
|
+
// Get updated profile
|
|
63
|
+
const userProfile = await databaseAdapter.findUserProfileById(auth.user.id);
|
|
64
|
+
return json({
|
|
65
|
+
success: true,
|
|
66
|
+
data: userProfile?.preferences || {}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error('Failed to update user preferences:', error);
|
|
71
|
+
return json({
|
|
72
|
+
success: false,
|
|
73
|
+
error: 'Failed to update user preferences',
|
|
74
|
+
message: error instanceof Error ? error.message : 'Unknown error'
|
|
75
|
+
}, { status: 500 });
|
|
76
|
+
}
|
|
77
|
+
};
|
|
@@ -21,10 +21,14 @@ export declare function getDocumentTypes(schemas: SchemaType[]): SchemaType[];
|
|
|
21
21
|
export declare function schemaExists(schemas: SchemaType[], name: string): boolean;
|
|
22
22
|
/**
|
|
23
23
|
* Get the available types for an array field
|
|
24
|
+
* Supports both schema references and inline object definitions
|
|
24
25
|
*/
|
|
25
26
|
export declare function getArrayTypes(schemas: SchemaType[], arrayField: {
|
|
26
27
|
of?: Array<{
|
|
27
28
|
type: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
fields?: any[];
|
|
28
32
|
}>;
|
|
29
33
|
}): SchemaType[];
|
|
30
34
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAEtF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAEpE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;GAGG;AAEH;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAEtF;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAEpE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,OAAO,EAAE,UAAU,EAAE,EACrB,UAAU,EAAE;IAAE,EAAE,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,GACzF,UAAU,EAAE,CA0Bd"}
|
|
@@ -28,10 +28,31 @@ export function schemaExists(schemas, name) {
|
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Get the available types for an array field
|
|
31
|
+
* Supports both schema references and inline object definitions
|
|
31
32
|
*/
|
|
32
33
|
export function getArrayTypes(schemas, arrayField) {
|
|
33
34
|
if (!arrayField.of)
|
|
34
35
|
return [];
|
|
35
|
-
const
|
|
36
|
-
|
|
36
|
+
const availableTypes = [];
|
|
37
|
+
arrayField.of.forEach((item) => {
|
|
38
|
+
// Check if this is an inline object definition
|
|
39
|
+
if (item.fields) {
|
|
40
|
+
// Create a temporary SchemaType from inline definition
|
|
41
|
+
const schemaName = item.name || item.type;
|
|
42
|
+
availableTypes.push({
|
|
43
|
+
type: 'object',
|
|
44
|
+
name: schemaName,
|
|
45
|
+
title: item.title || item.name || item.type,
|
|
46
|
+
fields: item.fields
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Look it up in the schema registry
|
|
51
|
+
const schema = schemas.find((s) => s.name === item.type);
|
|
52
|
+
if (schema) {
|
|
53
|
+
availableTypes.push(schema);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return availableTypes;
|
|
37
58
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/lib/schema-utils/validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAS,MAAM,kBAAkB,CAAC;AAkB1D;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAoMpE"}
|