MCPcopy
hub / github.com/directus/directus / createOne

Method createOne

api/src/services/collections.ts:65–267  ·  view source on GitHub ↗

* Create a single new collection

(payload: RawCollection, opts?: FieldMutationOptions)

Source from the content-addressed store, hash-verified

63 * Create a single new collection
64 */
65 async createOne(payload: RawCollection, opts?: FieldMutationOptions): Promise<string> {
66 if (this.accountability && this.accountability.admin !== true) {
67 throw new ForbiddenError();
68 }
69
70 if (!('collection' in payload)) throw new InvalidPayloadError({ reason: `"collection" is required` });
71
72 if (typeof payload.collection !== 'string' || payload.collection === '') {
73 throw new InvalidPayloadError({ reason: `"collection" must be a non-empty string` });
74 }
75
76 if (payload.collection.startsWith('directus_')) {
77 throw new InvalidPayloadError({ reason: `Collections can't start with "directus_"` });
78 }
79
80 if (payload.collection.includes('/')) {
81 throw new InvalidPayloadError({ reason: `Collection name can't contain "/"` });
82 }
83
84 if (payload.schema && payload.meta && (!('status' in payload.meta) || payload.meta.status === 'active')) {
85 await getEntitlementManager().assert('collections', { adding: 1, knex: this.knex });
86 }
87
88 payload.collection = await this.helpers.schema.parseCollectionName(payload.collection);
89
90 const nestedActionEvents: ActionEventParams[] = [];
91
92 try {
93 const existingCollections: string[] = [
94 ...((await this.knex.select('collection').from('directus_collections'))?.map(({ collection }) => collection) ??
95 []),
96 ...Object.keys(this.schema.collections),
97 ];
98
99 if (existingCollections.includes(payload.collection)) {
100 throw new InvalidPayloadError({ reason: `Collection "${payload.collection}" already exists` });
101 }
102
103 const attemptConcurrentIndex = Boolean(opts?.attemptConcurrentIndex);
104
105 // Create the collection/fields in a transaction so it'll be reverted in case of errors or
106 // permission problems. This might not work reliably in MySQL, as it doesn't support DDL in
107 // transactions.
108 await transaction(this.knex, async (trx) => {
109 if (payload.schema) {
110 if ('fields' in payload && !Array.isArray(payload.fields)) {
111 throw new InvalidPayloadError({ reason: `"fields" must be an array` });
112 }
113
114 /**
115 * Directus heavily relies on the primary key of a collection, so we have to make sure that
116 * every collection that is created has a primary key. If no primary key field is created
117 * while making the collection, we default to an auto incremented id named `id`
118 */
119
120 const injectedPrimaryKeyField: RawField = {
121 field: 'id',
122 type: 'integer',

Callers 3

generateTranslationsFunction · 0.95
createManyMethod · 0.95
resolveSystemAdminFunction · 0.95

Calls 15

addColumnToTableMethod · 0.95
createManyMethod · 0.95
createOneMethod · 0.95
addColumnIndexMethod · 0.95
addFieldFlagFunction · 0.90
getEntitlementManagerFunction · 0.85
transactionFunction · 0.85
shouldClearCacheFunction · 0.85
clearSystemCacheFunction · 0.85
getSchemaFunction · 0.85
assertMethod · 0.80
parseCollectionNameMethod · 0.80

Tested by

no test coverage detected