| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 | exports.up = knex => {  return knex.schema    // =====================================    // MODEL TABLES    // =====================================    // ASSETS ------------------------------    .createTable('assets', table => {      table.increments('id').primary()      table.string('filename').notNullable()      table.string('basename').notNullable()      table.string('ext').notNullable()      table.enum('kind', ['binary', 'image']).notNullable().defaultTo('binary')      table.string('mime').notNullable().defaultTo('application/octet-stream')      table.integer('fileSize').unsigned().comment('In kilobytes')      table.json('metadata')      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()      table.integer('folderId').unsigned().references('id').inTable('assetFolders')      table.integer('authorId').unsigned().references('id').inTable('users')    })    // ASSET FOLDERS -----------------------    .createTable('assetFolders', table => {      table.increments('id').primary()      table.string('name').notNullable()      table.string('slug').notNullable()      table.integer('parentId').unsigned().references('id').inTable('assetFolders')    })    // AUTHENTICATION ----------------------    .createTable('authentication', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.json('config').notNullable()      table.boolean('selfRegistration').notNullable().defaultTo(false)      table.json('domainWhitelist').notNullable()      table.json('autoEnrollGroups').notNullable()    })    // COMMENTS ----------------------------    .createTable('comments', table => {      table.increments('id').primary()      table.text('content').notNullable()      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()      table.integer('pageId').unsigned().references('id').inTable('pages')      table.integer('authorId').unsigned().references('id').inTable('users')    })    // EDITORS -----------------------------    .createTable('editors', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.json('config').notNullable()    })    // GROUPS ------------------------------    .createTable('groups', table => {      table.increments('id').primary()      table.string('name').notNullable()      table.json('permissions').notNullable()      table.json('pageRules').notNullable()      table.boolean('isSystem').notNullable().defaultTo(false)      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()    })    // LOCALES -----------------------------    .createTable('locales', table => {      table.string('code', 5).notNullable().primary()      table.json('strings')      table.boolean('isRTL').notNullable().defaultTo(false)      table.string('name').notNullable()      table.string('nativeName').notNullable()      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()    })    // LOGGING ----------------------------    .createTable('loggers', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.string('level').notNullable().defaultTo('warn')      table.json('config')    })    // NAVIGATION ----------------------------    .createTable('navigation', table => {      table.string('key').notNullable().primary()      table.json('config')    })    // PAGE HISTORY ------------------------    .createTable('pageHistory', table => {      table.increments('id').primary()      table.string('path').notNullable()      table.string('hash').notNullable()      table.string('title').notNullable()      table.string('description')      table.boolean('isPrivate').notNullable().defaultTo(false)      table.boolean('isPublished').notNullable().defaultTo(false)      table.string('publishStartDate')      table.string('publishEndDate')      table.text('content')      table.string('contentType').notNullable()      table.string('createdAt').notNullable()      table.integer('pageId').unsigned().references('id').inTable('pages')      table.string('editorKey').references('key').inTable('editors')      table.string('localeCode', 5).references('code').inTable('locales')      table.integer('authorId').unsigned().references('id').inTable('users')    })    // PAGES -------------------------------    .createTable('pages', table => {      table.increments('id').primary()      table.string('path').notNullable()      table.string('hash').notNullable()      table.string('title').notNullable()      table.string('description')      table.boolean('isPrivate').notNullable().defaultTo(false)      table.boolean('isPublished').notNullable().defaultTo(false)      table.string('privateNS')      table.string('publishStartDate')      table.string('publishEndDate')      table.text('content')      table.text('render')      table.json('toc')      table.string('contentType').notNullable()      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()      table.string('editorKey').references('key').inTable('editors')      table.string('localeCode', 5).references('code').inTable('locales')      table.integer('authorId').unsigned().references('id').inTable('users')      table.integer('creatorId').unsigned().references('id').inTable('users')    })    // PAGE TREE ---------------------------    .createTable('pageTree', table => {      table.increments('id').primary()      table.string('path').notNullable()      table.integer('depth').unsigned().notNullable()      table.string('title').notNullable()      table.boolean('isPrivate').notNullable().defaultTo(false)      table.boolean('isFolder').notNullable().defaultTo(false)      table.string('privateNS')      table.integer('parent').unsigned().references('id').inTable('pageTree')      table.integer('pageId').unsigned().references('id').inTable('pages')      table.string('localeCode', 5).references('code').inTable('locales')    })    // RENDERERS ---------------------------    .createTable('renderers', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.json('config')    })    // SEARCH ------------------------------    .createTable('searchEngines', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.json('config')    })    // SETTINGS ----------------------------    .createTable('settings', table => {      table.string('key').notNullable().primary()      table.json('value')      table.string('updatedAt').notNullable()    })    // STORAGE -----------------------------    .createTable('storage', table => {      table.string('key').notNullable().primary()      table.boolean('isEnabled').notNullable().defaultTo(false)      table.string('mode', ['sync', 'push', 'pull']).notNullable().defaultTo('push')      table.json('config')    })    // TAGS --------------------------------    .createTable('tags', table => {      table.increments('id').primary()      table.string('tag').notNullable().unique()      table.string('title')      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()    })    // USER KEYS ---------------------------    .createTable('userKeys', table => {      table.increments('id').primary()      table.string('kind').notNullable()      table.string('token').notNullable()      table.string('createdAt').notNullable()      table.string('validUntil').notNullable()      table.integer('userId').unsigned().references('id').inTable('users')    })    // USERS -------------------------------    .createTable('users', table => {      table.increments('id').primary()      table.string('email').notNullable()      table.string('name').notNullable()      table.string('providerId')      table.string('password')      table.boolean('tfaIsActive').notNullable().defaultTo(false)      table.string('tfaSecret')      table.string('jobTitle').defaultTo('')      table.string('location').defaultTo('')      table.string('pictureUrl')      table.string('timezone').notNullable().defaultTo('America/New_York')      table.boolean('isSystem').notNullable().defaultTo(false)      table.boolean('isActive').notNullable().defaultTo(false)      table.boolean('isVerified').notNullable().defaultTo(false)      table.string('createdAt').notNullable()      table.string('updatedAt').notNullable()      table.string('providerKey').references('key').inTable('authentication').notNullable().defaultTo('local')      table.string('localeCode', 5).references('code').inTable('locales').notNullable().defaultTo('en')      table.string('defaultEditor').references('key').inTable('editors').notNullable().defaultTo('markdown')    })    // =====================================    // RELATION TABLES    // =====================================    // PAGE HISTORY TAGS ---------------------------    .createTable('pageHistoryTags', table => {      table.increments('id').primary()      table.integer('pageId').unsigned().references('id').inTable('pageHistory').onDelete('CASCADE')      table.integer('tagId').unsigned().references('id').inTable('tags').onDelete('CASCADE')    })    // PAGE TAGS ---------------------------    .createTable('pageTags', table => {      table.increments('id').primary()      table.integer('pageId').unsigned().references('id').inTable('pages').onDelete('CASCADE')      table.integer('tagId').unsigned().references('id').inTable('tags').onDelete('CASCADE')    })    // USER GROUPS -------------------------    .createTable('userGroups', table => {      table.increments('id').primary()      table.integer('userId').unsigned().references('id').inTable('users').onDelete('CASCADE')      table.integer('groupId').unsigned().references('id').inTable('groups').onDelete('CASCADE')    })    // =====================================    // REFERENCES    // =====================================    .table('users', table => {      table.unique(['providerKey', 'email'])    })}exports.down = knex => {  return knex.schema    .dropTableIfExists('userGroups')    .dropTableIfExists('pageHistoryTags')    .dropTableIfExists('pageHistory')    .dropTableIfExists('pageTags')    .dropTableIfExists('assets')    .dropTableIfExists('assetFolders')    .dropTableIfExists('comments')    .dropTableIfExists('editors')    .dropTableIfExists('groups')    .dropTableIfExists('locales')    .dropTableIfExists('navigation')    .dropTableIfExists('pages')    .dropTableIfExists('renderers')    .dropTableIfExists('settings')    .dropTableIfExists('storage')    .dropTableIfExists('tags')    .dropTableIfExists('userKeys')    .dropTableIfExists('users')}
 |