diff --git a/.gitignore b/.gitignore index 3e09d15a11..8122c44a91 100644 --- a/.gitignore +++ b/.gitignore @@ -1,109 +1,8 @@ -.DS_Store - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) +node_modules .cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - +.env +.DS_Store uploads - +debug.db +test +dist diff --git a/package-lock.json b/package-lock.json index 7fc627b317..7a57110522 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "api-node", - "version": "9.0.0-alpha.3", + "name": "directus", + "version": "0.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/cli/create/index.ts b/src/cli/create/index.ts index 7f16b02029..d5d5dbb404 100644 --- a/src/cli/create/index.ts +++ b/src/cli/create/index.ts @@ -39,7 +39,7 @@ export default async function create(directory: string, options: Record = {}; @@ -13,10 +14,12 @@ for (let [key, value] of Object.entries(process.env)) { if (key.startsWith('db') === false) continue; if (key === 'db_client') continue; + key = key.slice(3); // remove `DB_` + connectionConfig[camelCase(key)] = value; } -const database = knex({ +const knexConfig: Config = { client: process.env.DB_CLIENT, connection: connectionConfig, migrations: { @@ -27,7 +30,13 @@ const database = knex({ extension: 'ts', directory: './src/database/seeds/', }, -}); +}; + +if (process.env.DB_CLIENT === 'sqlite3') { + knexConfig.useNullAsDefault = true; +} + +const database = knex(knexConfig); export const schemaInspector = SchemaInspector(database); diff --git a/src/database/run-ast.ts b/src/database/run-ast.ts index f5a55a7bed..30c3514e28 100644 --- a/src/database/run-ast.ts +++ b/src/database/run-ast.ts @@ -80,7 +80,7 @@ export default async function runAST(ast: AST, query = ast.query) { .forEach((column) => { dbQuery.orWhereRaw( `LOWER(${column.name}) LIKE '%' || LOWER(?) || '%'`, - query.search + query.search! ); }); } @@ -91,8 +91,8 @@ export default async function runAST(ast: AST, query = ast.query) { const m2o = isM2O(batch); let batchQuery: Query = {}; - let tempField: string = null; - let tempLimit: number = null; + let tempField: string; + let tempLimit: number; if (m2o) { // Make sure we always fetch the nested items primary key field to ensure we have the key to match the item by diff --git a/src/database/seeds/01-create-tables.ts b/src/database/seeds/01-create-tables.ts index afffb41d0b..56e6263fd9 100644 --- a/src/database/seeds/01-create-tables.ts +++ b/src/database/seeds/01-create-tables.ts @@ -1,19 +1,10 @@ import * as Knex from 'knex'; export async function seed(knex: Knex): Promise { - await knex.schema.dropTableIfExists('directus_activity'); - await knex.schema.createTable('directus_activity', (table) => { - table.increments().notNullable(); - table.string('action', 45).notNullable(); - table.uuid('action_by'); - table.timestamp('action_on').defaultTo(knex.fn.now()).notNullable(); - table.string('ip', 50).notNullable(); - table.string('user_agent').notNullable(); - table.string('collection', 64).notNullable(); - table.string('item').notNullable(); - table.text('comment'); - }); - + /** + * @NOTE + * The order here matters because of the foreign key constraints + */ await knex.schema.dropTableIfExists('directus_collections'); await knex.schema.createTable('directus_collections', (table) => { table.string('collection').primary(); @@ -24,106 +15,6 @@ export async function seed(knex: Knex): Promise { table.json('translation'); }); - await knex.schema.dropTableIfExists('directus_fields'); - await knex.schema.createTable('directus_fields', (table) => { - table.increments().notNullable(); - table.string('collection', 64).notNullable(); - table.string('field', 64).notNullable(); - table.string('special', 64); - table.string('interface', 64); - table.json('options'); - table.string('display', 64); - table.json('display_options'); - table.boolean('locked').notNullable().defaultTo(false); - table.boolean('required').notNullable().defaultTo(false); - table.boolean('readonly').notNullable().defaultTo(false); - table.boolean('hidden_detail').notNullable().defaultTo(false); - table.boolean('hidden_browse').notNullable().defaultTo(false); - table.integer('sort'); - table.string('width', 30); - table.integer('group'); - table.json('translation'); - }); - - await knex.schema.dropTableIfExists('directus_files'); - await knex.schema.createTable('directus_files', (table) => { - table.uuid('id').primary().notNullable(); - table.string('storage', 50).notNullable(); - table.string('filename_disk', 255).notNullable(); - table.string('filename_download', 255).notNullable(); - table.string('title', 255); - table.string('type', 255); - table.uuid('uploaded_by'); - table.timestamp('uploaded_on').notNullable().defaultTo(knex.fn.now()); - table.string('charset', 50); - table.integer('filesize'); - table.integer('width'); - table.integer('height'); - table.integer('duration'); - table.string('embed', 200); - table.uuid('folder'); - table.text('description'); - table.text('location'); - table.text('tags'); - table.json('metadata'); - }); - - await knex.schema.dropTableIfExists('directus_folders'); - await knex.schema.createTable('directus_folders', (table) => { - table.uuid('id').primary().notNullable(); - table.string('name', 255).notNullable(); - table.uuid('parent_folder'); - }); - - await knex.schema.dropTableIfExists('directus_permissions'); - await knex.schema.createTable('directus_permissions', (table) => { - table.increments(); - table.uuid('role'); - table.string('collection', 64).notNullable(); - table.string('operation', 10).notNullable(); - table.json('permissions').notNullable().defaultTo('{}'); - table.json('presets'); - table.text('fields'); - table.integer('limit'); - }); - - await knex.schema.dropTableIfExists('directus_presets'); - await knex.schema.createTable('directus_presets', (table) => { - table.increments().notNullable(); - table.string('title'); - table.uuid('user'); - table.string('collection', 64).notNullable(); - table.string('search_query', 100); - table.json('filters'); - table.string('view_type', 100).notNullable(); - table.json('view_query'); - table.json('view_options'); - table.uuid('role'); - }); - - await knex.schema.dropTableIfExists('directus_relations'); - await knex.schema.createTable('directus_relations', (table) => { - table.increments(); - table.string('collection_many', 64).notNullable(); - table.string('field_many', 64).notNullable(); - table.string('primary_many', 64); - table.string('collection_one', 64); - table.string('field_one', 64); - table.string('primary_one', 64); - table.string('junction_field', 64); - }); - - await knex.schema.dropTableIfExists('directus_revisions'); - await knex.schema.createTable('directus_revisions', (table) => { - table.increments(); - table.integer('activity').notNullable(); - table.string('collection', 64).notNullable(); - table.string('item', 255).notNullable(); - table.json('data'); - table.json('delta'); - table.integer('parent'); - }); - await knex.schema.dropTableIfExists('directus_roles'); await knex.schema.createTable('directus_roles', (table) => { table.uuid('id').primary(); @@ -137,31 +28,6 @@ export async function seed(knex: Knex): Promise { table.boolean('app_access').notNullable().defaultTo(true); }); - await knex.schema.dropTableIfExists('directus_sessions'); - await knex.schema.createTable('directus_sessions', (table) => { - table.increments(); - table.uuid('user').notNullable(); - table.timestamp('expires').notNullable(); - table.string('ip', 255); - table.string('user_agent', 255); - }); - - await knex.schema.dropTableIfExists('directus_settings'); - await knex.schema.createTable('directus_settings', (table) => { - table.increments(); - table.string('project_name', 100); - table.string('project_url', 255); - table.string('project_color', 10); - table.json('asset_shortcuts'); - table.string('asset_generation', 15); - table.uuid('project_foreground'); - table.uuid('project_background'); - - /** - * @todo extend with all settings - */ - }); - await knex.schema.dropTableIfExists('directus_users'); await knex.schema.createTable('directus_users', (table) => { table.uuid('id').primary(); @@ -181,6 +47,161 @@ export async function seed(knex: Knex): Promise { table.string('2fa_secret', 255); table.string('theme', 20); table.uuid('role'); + table.foreign('role').references('id').inTable('directus_roles'); + }); + + await knex.schema.dropTableIfExists('directus_fields'); + await knex.schema.createTable('directus_fields', (table) => { + table.increments().notNullable(); + table.string('collection', 64).notNullable(); + table.foreign('collection').references('collection').inTable('directus_collections'); + table.string('field', 64).notNullable(); + table.string('special', 64); + table.string('interface', 64); + table.json('options'); + table.string('display', 64); + table.json('display_options'); + table.boolean('locked').notNullable().defaultTo(false); + table.boolean('required').notNullable().defaultTo(false); + table.boolean('readonly').notNullable().defaultTo(false); + table.boolean('hidden_detail').notNullable().defaultTo(false); + table.boolean('hidden_browse').notNullable().defaultTo(false); + table.integer('sort'); + table.string('width', 30); + table.integer('group'); + table.json('translation'); + }); + + await knex.schema.dropTableIfExists('directus_activity'); + await knex.schema.createTable('directus_activity', (table) => { + table.increments().notNullable(); + table.string('action', 45).notNullable(); + table.uuid('action_by'); + table.foreign('action_by').references('id').inTable('directus_users'); + table.timestamp('action_on').defaultTo(knex.fn.now()).notNullable(); + table.string('ip', 50).notNullable(); + table.string('user_agent').notNullable(); + table.string('collection', 64).notNullable(); + table.foreign('collection').references('collection').inTable('directus_collections'); + table.string('item').notNullable(); + table.text('comment'); + }); + + await knex.schema.dropTableIfExists('directus_folders'); + await knex.schema.createTable('directus_folders', (table) => { + table.uuid('id').primary().notNullable(); + table.string('name', 255).notNullable(); + table.uuid('parent_folder'); + table.foreign('parent_folder').references('id').inTable('directus_folders'); + }); + + await knex.schema.dropTableIfExists('directus_files'); + await knex.schema.createTable('directus_files', (table) => { + table.uuid('id').primary().notNullable(); + table.string('storage', 50).notNullable(); + table.string('filename_disk', 255).notNullable(); + table.string('filename_download', 255).notNullable(); + table.string('title', 255); + table.string('type', 255); + table.uuid('uploaded_by'); + table.timestamp('uploaded_on').notNullable().defaultTo(knex.fn.now()); + table.string('charset', 50); + table.integer('filesize'); + table.integer('width'); + table.integer('height'); + table.integer('duration'); + table.string('embed', 200); + table.uuid('folder'); + table.foreign('folder').references('id').inTable('directus_folders'); + table.text('description'); + table.text('location'); + table.text('tags'); + table.json('metadata'); + }); + + await knex.schema.dropTableIfExists('directus_permissions'); + await knex.schema.createTable('directus_permissions', (table) => { + table.increments(); + table.uuid('role'); + table.foreign('role').references('id').inTable('directus_roles'); + table.string('collection', 64).notNullable(); + table.foreign('collection').references('collection').inTable('directus_collections'); + table.string('operation', 10).notNullable(); + table.json('permissions').notNullable().defaultTo('{}'); + table.json('presets'); + table.text('fields'); + table.integer('limit'); + }); + + await knex.schema.dropTableIfExists('directus_presets'); + await knex.schema.createTable('directus_presets', (table) => { + table.increments().notNullable(); + table.string('title'); + table.uuid('user'); + table.foreign('user').references('id').inTable('directus_users'); + table.string('collection', 64).notNullable(); + table.foreign('collection').references('collection').inTable('directus_collections'); + table.string('search_query', 100); + table.json('filters'); + table.string('view_type', 100).notNullable(); + table.json('view_query'); + table.json('view_options'); + table.uuid('role'); + }); + + await knex.schema.dropTableIfExists('directus_relations'); + await knex.schema.createTable('directus_relations', (table) => { + table.increments(); + table.string('collection_many', 64).notNullable(); + table.foreign('collection_many').references('collection').inTable('directus_collections'); + table.string('field_many', 64).notNullable(); + table.string('primary_many', 64); + table.string('collection_one', 64); + table.foreign('collection_one').references('collection').inTable('directus_collections'); + table.string('field_one', 64); + table.string('primary_one', 64); + table.string('junction_field', 64); + }); + + await knex.schema.dropTableIfExists('directus_revisions'); + await knex.schema.createTable('directus_revisions', (table) => { + table.increments(); + table.integer('activity').notNullable(); + table.foreign('id').references('id').inTable('directus_activity'); + table.string('collection', 64).notNullable(); + table.foreign('collection').references('collection').inTable('directus_collections'); + table.string('item', 255).notNullable(); + table.json('data'); + table.json('delta'); + table.integer('parent'); + }); + + await knex.schema.dropTableIfExists('directus_sessions'); + await knex.schema.createTable('directus_sessions', (table) => { + table.increments(); + table.uuid('user').notNullable(); + table.foreign('user').references('id').inTable('directus_users'); + table.timestamp('expires').notNullable(); + table.string('ip', 255); + table.string('user_agent', 255); + }); + + await knex.schema.dropTableIfExists('directus_settings'); + await knex.schema.createTable('directus_settings', (table) => { + table.increments(); + table.string('project_name', 100); + table.string('project_url', 255); + table.string('project_color', 10); + table.json('asset_shortcuts'); + table.string('asset_generation', 15); + table.uuid('project_foreground'); + table.foreign('project_foreground').references('id').inTable('directus_files'); + table.uuid('project_background'); + table.foreign('project_background').references('id').inTable('directus_files'); + + /** + * @todo extend with all settings + */ }); await knex.schema.dropTableIfExists('directus_webhooks'); diff --git a/src/database/seeds/02-add-foreign-key-constraints.ts b/src/database/seeds/02-add-foreign-key-constraints.ts deleted file mode 100644 index c737008722..0000000000 --- a/src/database/seeds/02-add-foreign-key-constraints.ts +++ /dev/null @@ -1,48 +0,0 @@ -import * as Knex from 'knex'; - -export async function seed(knex: Knex): Promise { - await knex.schema.table('directus_activity', (table) => { - table.foreign('collection').references('collection').inTable('directus_collections'); - table.foreign('action_by').references('id').inTable('directus_users'); - }); - - await knex.schema.table('directus_fields', (table) => { - table.foreign('collection').references('collection').inTable('directus_collections'); - }); - - await knex.schema.table('directus_files', (table) => { - table.foreign('folder').references('id').inTable('directus_folders'); - }); - - await knex.schema.table('directus_folders', (table) => { - table.foreign('parent_folder').references('id').inTable('directus_folders'); - }); - - await knex.schema.table('directus_permissions', (table) => { - table.foreign('role').references('id').inTable('directus_roles'); - table.foreign('collection').references('collection').inTable('directus_collections'); - }); - - await knex.schema.table('directus_presets', (table) => { - table.foreign('user').references('id').inTable('directus_users'); - table.foreign('collection').references('collection').inTable('directus_collections'); - }); - - await knex.schema.table('directus_relations', (table) => { - table.foreign('collection_many').references('collection').inTable('directus_collections'); - table.foreign('collection_one').references('collection').inTable('directus_collections'); - }); - - await knex.schema.table('directus_revisions', (table) => { - table.foreign('collection').references('collection').inTable('directus_collections'); - }); - - await knex.schema.table('directus_sessions', (table) => { - table.foreign('user').references('id').inTable('directus_users'); - }); - - await knex.schema.table('directus_settings', (table) => { - table.foreign('project_foreground').references('id').inTable('directus_files'); - table.foreign('project_background').references('id').inTable('directus_files'); - }); -} diff --git a/src/database/seeds/03-add-system-rows.ts b/src/database/seeds/02-add-system-rows.ts similarity index 96% rename from src/database/seeds/03-add-system-rows.ts rename to src/database/seeds/02-add-system-rows.ts index f962126d02..10c8f6c686 100644 --- a/src/database/seeds/03-add-system-rows.ts +++ b/src/database/seeds/02-add-system-rows.ts @@ -119,14 +119,14 @@ const systemData = [ }, ], }, - { - table: 'directus_fields', - rows: [ - /** - * @todo add final system fields setup for admin app - */ - ], - }, + // { + // table: 'directus_fields', + // rows: [ + // /** + // * @todo add final system fields setup for admin app + // */ + // ], + // }, { table: 'directus_relations', rows: [ @@ -237,7 +237,7 @@ const systemData = [ project_name: 'Directus', project_url: null, project_color: '#2d6cc0', - asset_shortcuts: [], + asset_shortcuts: '[]', asset_generation: 'all', project_foreground: null, project_background: null, @@ -248,7 +248,6 @@ const systemData = [ export async function seed(knex: Knex): Promise { for (const { table, rows } of systemData) { - console.log(table, rows); await knex(table).insert(rows); } } diff --git a/src/knex-schema-inspector b/src/knex-schema-inspector index db80aeec75..5b8b224eac 160000 --- a/src/knex-schema-inspector +++ b/src/knex-schema-inspector @@ -1 +1 @@ -Subproject commit db80aeec753db76b7d854f2ccc1ccc3b967b4601 +Subproject commit 5b8b224eacb0286dbafb14c2e88576927673374d