Merge branch 'refactorSchemas' of https://github.com/adi2412/codecombat into adi2412-refactorSchemas

This commit is contained in:
Scott Erickson 2014-04-12 08:53:24 -07:00
commit 5a794306fe
46 changed files with 98 additions and 72 deletions

View file

@ -2,13 +2,6 @@ storage = require 'lib/storage'
deltasLib = require 'lib/deltas'
auth = require 'lib/auth'
class CocoSchema extends Backbone.Model
constructor: (path, args...) ->
super(args...)
@urlRoot = path + '/schema'
window.CocoSchema = CocoSchema
class CocoModel extends Backbone.Model
idAttribute: "_id"
loaded: false
@ -18,7 +11,7 @@ class CocoModel extends Backbone.Model
initialize: ->
super()
@constructor.schema ?= new CocoSchema(@urlRoot)
@constructor.schema ?= @urlRoot[4..].replace '.', '_'
if not @constructor.className
console.error("#{@} needs a className set.")
@markToRevert()
@ -65,8 +58,8 @@ class CocoModel extends Backbone.Model
loadSchema: ->
return if @constructor.schema.loading
@constructor.schema.fetch()
@listenToOnce(@constructor.schema, 'sync', @onConstructorSync)
@constructor.schema = require 'schemas/' + @constructor.schema + '_schema' unless @constructor.schema.loaded
@onConstructorSync()
onConstructorSync: ->
@constructor.schema.loaded = true
@ -77,7 +70,7 @@ class CocoModel extends Backbone.Model
schema: -> return @constructor.schema
validate: ->
result = tv4.validateMultiple(@attributes, @constructor.schema?.attributes or {})
result = tv4.validateMultiple(@attributes, @constructor.schema? or {})
if result.errors?.length
console.log @, "got validate result with errors:", result
return result.errors unless result.valid
@ -138,11 +131,11 @@ class CocoModel extends Backbone.Model
addSchemaDefaults: ->
return if @addedSchemaDefaults or not @constructor.hasSchema()
@addedSchemaDefaults = true
for prop, defaultValue of @constructor.schema.attributes.default or {}
for prop, defaultValue of @constructor.schema.default or {}
continue if @get(prop)?
#console.log "setting", prop, "to", defaultValue, "from attributes.default"
@set prop, defaultValue
for prop, sch of @constructor.schema.attributes.properties or {}
for prop, sch of @constructor.schema.properties or {}
continue if @get(prop)?
#console.log "setting", prop, "to", sch.default, "from sch.default" if sch.default?
@set prop, sch.default if sch.default?
@ -154,7 +147,7 @@ class CocoModel extends Backbone.Model
# returns unfetched model shells for every referenced doc in this model
# OPTIMIZE so that when loading models, it doesn't cause the site to stutter
data ?= @attributes
schema ?= @schema().attributes
schema ?= @schema()
models = []
if $.isArray(data) and schema.items?
@ -242,7 +235,7 @@ class CocoModel extends Backbone.Model
getExpandedDelta: ->
delta = @getDelta()
deltasLib.expandDelta(delta, @_revertAttributes, @schema().attributes)
deltasLib.expandDelta(delta, @_revertAttributes, @schema())
addPatchToAcceptOnSave: (patch) ->
@acceptedPatches ?= []

View file

@ -29,9 +29,9 @@ class SuperModel
model.loadSchema()
schema = model.schema()
unless schema.loaded
@schemas[schema.urlRoot] = schema
@schemas[model.urlRoot] = schema
return schema.once('sync', => @modelLoaded(model))
refs = model.getReferencedModels(model.attributes, schema.attributes, '/', @shouldLoadProjection)
refs = model.getReferencedModels(model.attributes, schema, '/', @shouldLoadProjection)
refs = [] unless @mustPopulate is model or @shouldPopulate(model)
# console.log 'Loaded', model.get('name')
for ref, i in refs when @shouldLoadReference ref

View file

@ -1,4 +1,4 @@
c = require '../commons/schemas'
c = require './schemas'
ArticleSchema = c.object()
c.extendNamedProperties ArticleSchema # name first

View file

@ -0,0 +1,34 @@
locale = require '../locale/locale' # requiring from app; will break if we stop serving from where app lives
languages = []
for code, localeInfo of locale
languages.push code: code, nativeDescription: localeInfo.nativeDescription, englishDescription: localeInfo.englishDescription
module.exports.languages = languages
module.exports.languageCodes = languageCodes = (language.code for language in languages)
module.exports.languageCodesLower = languageCodesLower = (code.toLowerCase() for code in languageCodes)
# Keep keys lower-case for matching and values with second subtag uppercase like i18next expects
languageAliases =
'en': 'en-US'
'zh-cn': 'zh-HANS'
'zh-hans-cn': 'zh-HANS'
'zh-sg': 'zh-HANS'
'zh-hans-sg': 'zh-HANS'
'zh-tw': 'zh-HANT'
'zh-hant-tw': 'zh-HANT'
'zh-hk': 'zh-HANT'
'zh-hant-hk': 'zh-HANT'
'zh-mo': 'zh-HANT'
'zh-hant-mo': 'zh-HANT'
module.exports.languageCodeFromAcceptedLanguages = languageCodeFromAcceptedLanguages = (acceptedLanguages) ->
for lang in acceptedLanguages ? []
code = languageAliases[lang.toLowerCase()]
return code if code
codeIndex = _.indexOf languageCodesLower, lang
if codeIndex isnt -1
return languageCodes[codeIndex]
return 'en-US'

View file

@ -1,5 +1,5 @@
c = require '../../commons/schemas'
metaschema = require '../../commons/metaschema'
c = require './schemas'
metaschema = require './metaschema'
attackSelfCode = """
class AttacksSelf extends Component

View file

@ -1,4 +1,4 @@
c = require '../../commons/schemas'
c = require './schemas'
LevelFeedbackLevelSchema = c.object {required: ['original', 'majorVersion']}, {
original: c.objectId({})

View file

@ -1,5 +1,5 @@
c = require '../commons/schemas'
ThangComponentSchema = require './thangs/thang_component_schema'
c = require './schemas'
ThangComponentSchema = require './thang_component_schema'
SpecificArticleSchema = c.object()
c.extendNamedProperties SpecificArticleSchema # name first

View file

@ -1,4 +1,4 @@
c = require '../../commons/schemas'
c = require './schemas'
LevelSessionPlayerSchema = c.object
id: c.objectId

View file

@ -1,5 +1,5 @@
c = require '../../commons/schemas'
metaschema = require '../../commons/metaschema'
c = require './schemas'
metaschema = require './metaschema'
jitterSystemCode = """
class Jitter extends System

View file

@ -1,4 +1,4 @@
c = require '../commons/schemas'
c = require './schemas'
patchables = ['level', 'thang_type', 'level_system', 'level_component', 'article']

View file

@ -1,5 +1,5 @@
#language imports
Language = require '../routes/languages'
Language = require './languages'
# schema helper methods
me = module.exports

View file

@ -1,4 +1,4 @@
c = require '../../commons/schemas'
c = require './schemas'
module.exports = ThangComponentSchema = c.object {
title: "Component"

View file

@ -1,4 +1,4 @@
c = require '../../commons/schemas'
c = require './schemas'
ThangComponentSchema = require './thang_component_schema'
ThangTypeSchema = c.object()

View file

@ -1,4 +1,4 @@
c = require '../commons/schemas'
c = require './schemas'
emailSubscriptions = ['announcement', 'tester', 'level_creator', 'developer', 'article_editor', 'translator', 'support', 'notification']
UserSchema = c.object {},

View file

@ -29,7 +29,7 @@ module.exports = class JobProfileView extends CocoView
visibleSettings = @editableSettings.concat @readOnlySettings
data = _.pick (me.get('jobProfile') ? {}), (value, key) => key in visibleSettings
data.name ?= (me.get('firstName') + ' ' + me.get('lastName')).trim() if me.get('firstName')
schema = _.cloneDeep me.schema().get('properties').jobProfile
schema = _.cloneDeep me.schema().properties.jobProfile
schema.properties = _.pick schema.properties, (value, key) => key in visibleSettings
schema.required = _.intersection schema.required, visibleSettings
for prop in @readOnlySettings

View file

@ -82,8 +82,8 @@ module.exports = class SettingsView extends View
buildPictureTreema: ->
data = photoURL: me.get('photoURL')
data.photoURL = null if data.photoURL?.search('gravatar') isnt -1 # Old style
schema = _.cloneDeep me.schema().attributes
schema.properties = _.pick me.schema().get('properties'), 'photoURL'
schema = _.cloneDeep me.schema()
schema.properties = _.pick me.schema().properties, 'photoURL'
schema.required = ['photoURL']
treemaOptions =
filePath: "db/user/#{me.id}"

View file

@ -54,7 +54,7 @@ module.exports = class ArticleEditView extends View
options =
data: data
filePath: "db/thang.type/#{@article.get('original')}"
schema: Article.schema.attributes
schema: Article.schema
readOnly: true unless me.isAdmin() or @article.hasWriteAccess(me)
callbacks:
change: @pushChangesToPreview

View file

@ -45,7 +45,7 @@ module.exports = class ThangComponentEditView extends CocoView
buildExtantComponentTreema: ->
treemaOptions =
supermodel: @supermodel
schema: Level.schema.get('properties').thangs.items.properties.components
schema: Level.schema.properties.thangs.items.properties.components
data: _.cloneDeep @components
callbacks: {select: @onSelectExtantComponent, change:@onChangeExtantComponents}
noSortable: true
@ -69,7 +69,7 @@ module.exports = class ThangComponentEditView extends CocoView
treemaOptions =
supermodel: @supermodel
schema: { type: 'array', items: LevelComponent.schema.attributes }
schema: { type: 'array', items: LevelComponent.schema }
data: ($.extend(true, {}, c) for c in components)
callbacks: {select: @onSelectAddableComponent, enter: @onAddComponentEnterPressed }
readOnly: true

View file

@ -31,7 +31,7 @@ module.exports = class LevelComponentEditView extends View
buildSettingsTreema: ->
data = _.pick @levelComponent.attributes, (value, key) => key in @editableSettings
schema = _.cloneDeep LevelComponent.schema.attributes
schema = _.cloneDeep LevelComponent.schema
schema.properties = _.pick schema.properties, (value, key) => key in @editableSettings
schema.required = _.intersection schema.required, @editableSettings
@ -55,7 +55,7 @@ module.exports = class LevelComponentEditView extends View
buildConfigSchemaTreema: ->
treemaOptions =
supermodel: @supermodel
schema: LevelComponent.schema.get('properties').configSchema
schema: LevelComponent.schema.properties.configSchema
data: @levelComponent.get 'configSchema'
callbacks: {change: @onConfigSchemaEdited}
treemaOptions.readOnly = true unless me.isAdmin()
@ -63,7 +63,7 @@ module.exports = class LevelComponentEditView extends View
@configSchemaTreema.build()
@configSchemaTreema.open()
# TODO: schema is not loaded for the first one here?
@configSchemaTreema.tv4.addSchema('metaschema', LevelComponent.schema.get('properties').configSchema)
@configSchemaTreema.tv4.addSchema('metaschema', LevelComponent.schema.properties.configSchema)
onConfigSchemaEdited: =>
@levelComponent.set 'configSchema', @configSchemaTreema.data

View file

@ -22,7 +22,7 @@ module.exports = class ScriptsTabView extends View
@dimensions = @level.dimensions()
scripts = $.extend(true, [], @level.get('scripts') ? [])
treemaOptions =
schema: Level.schema.get('properties').scripts
schema: Level.schema.properties.scripts
data: scripts
callbacks:
change: @onScriptsChanged
@ -52,7 +52,7 @@ module.exports = class ScriptsTabView extends View
filePath: "db/level/#{@level.get('original')}"
files: @files
view: @
schema: Level.schema.get('properties').scripts.items
schema: Level.schema.properties.scripts.items
data: selected.data
thangIDs: thangIDs
dimensions: @dimensions

View file

@ -25,7 +25,7 @@ module.exports = class SettingsTabView extends View
onLevelLoaded: (e) ->
@level = e.level
data = _.pick @level.attributes, (value, key) => key in @editableSettings
schema = _.cloneDeep Level.schema.attributes
schema = _.cloneDeep Level.schema
schema.properties = _.pick schema.properties, (value, key) => key in @editableSettings
schema.required = _.intersection schema.required, @editableSettings
thangIDs = @getThangIDs()

View file

@ -29,7 +29,7 @@ module.exports = class LevelSystemEditView extends View
buildSettingsTreema: ->
data = _.pick @levelSystem.attributes, (value, key) => key in @editableSettings
schema = _.cloneDeep LevelSystem.schema.attributes
schema = _.cloneDeep LevelSystem.schema
schema.properties = _.pick schema.properties, (value, key) => key in @editableSettings
schema.required = _.intersection schema.required, @editableSettings
@ -53,7 +53,7 @@ module.exports = class LevelSystemEditView extends View
buildConfigSchemaTreema: ->
treemaOptions =
supermodel: @supermodel
schema: LevelSystem.schema.get('properties').configSchema
schema: LevelSystem.schema.properties.configSchema
data: @levelSystem.get 'configSchema'
callbacks: {change: @onConfigSchemaEdited}
treemaOptions.readOnly = true unless me.isAdmin()
@ -61,7 +61,7 @@ module.exports = class LevelSystemEditView extends View
@configSchemaTreema.build()
@configSchemaTreema.open()
# TODO: schema is not loaded for the first one here?
@configSchemaTreema.tv4.addSchema('metaschema', LevelSystem.schema.get('properties').configSchema)
@configSchemaTreema.tv4.addSchema('metaschema', LevelSystem.schema.properties.configSchema)
onConfigSchemaEdited: =>
@levelSystem.set 'configSchema', @configSchemaTreema.data

View file

@ -67,7 +67,7 @@ module.exports = class SystemsTabView extends View
treemaOptions =
# TODO: somehow get rid of the + button, or repurpose it to open the LevelSystemAddView instead
supermodel: @supermodel
schema: Level.schema.get('properties').systems
schema: Level.schema.properties.systems
data: systems
readOnly: true unless me.isAdmin() or @level.hasWriteAccess(me)
callbacks:

View file

@ -140,7 +140,7 @@ module.exports = class ThangsTabView extends View
return if @startsLoading
data = $.extend(true, {}, @level.attributes)
treemaOptions =
schema: Level.schema.get('properties').thangs
schema: Level.schema.properties.thangs
data: data.thangs
supermodel: @supermodel
callbacks:

View file

@ -12,7 +12,7 @@ module.exports = class ColorsTabView extends CocoView
constructor: (@thangType, options) ->
@listenToOnce(@thangType, 'sync', @tryToBuild)
@listenToOnce(@thangType.schema(), 'sync', @tryToBuild)
# @listenToOnce(@thangType.schema(), 'sync', @tryToBuild)
@colorConfig = { hue: 0, saturation: 0.5, lightness: 0.5 }
@spriteBuilder = new SpriteBuilder(@thangType)
f = =>
@ -115,7 +115,7 @@ module.exports = class ColorsTabView extends CocoView
return unless @thangType.loaded and @thangType.schema().loaded
data = @thangType.get('colorGroups')
data ?= {}
schema = @thangType.schema().attributes.properties?.colorGroups
schema = @thangType.schema().properties?.colorGroups
treemaOptions =
data: data
schema: schema

View file

@ -62,7 +62,6 @@ module.exports = class ThangTypeEditView extends View
@thangType.fetch()
@thangType.loadSchema()
@listenToOnce(@thangType.schema(), 'sync', @onThangTypeSync)
@listenToOnce(@thangType, 'sync', @onThangTypeSync)
@refreshAnimation = _.debounce @refreshAnimation, 500
@ -344,7 +343,7 @@ module.exports = class ThangTypeEditView extends View
buildTreema: ->
data = @getThangData()
schema = _.cloneDeep ThangType.schema.attributes
schema = _.cloneDeep ThangType.schema
schema.properties = _.pick schema.properties, (value, key) => not (key in ['components'])
options =
data: data

View file

@ -96,7 +96,7 @@ module.exports = class SearchView extends View
name = @$el.find('#name').val()
model = new @model()
model.set('name', name)
if @model.schema.get('properties').permissions
if @model.schema.properties.permissions
model.set 'permissions', [{access: 'owner', target: me.id}]
res = model.save()
return unless res

View file

@ -36,7 +36,7 @@ module.exports = class LoginModalView extends View
loginAccount: (e) =>
forms.clearFormAlerts(@$el)
userObject = forms.formToObject @$el
res = tv4.validateMultiple userObject, User.schema.attributes
res = tv4.validateMultiple userObject, User.schema
return forms.applyErrorsToForm(@$el, res.errors) unless res.valid
@enableModalInProgress(@$el) # TODO: part of forms
loginUser(userObject)

View file

@ -57,7 +57,7 @@ module.exports = class SignupModalView extends View
userObject.emailSubscriptions.push 'notification' unless 'notification' in userObject.emailSubscriptions
else
userObject.emailSubscriptions = _.without (userObject.emailSubscriptions ? []), 'announcement', 'notification'
res = tv4.validateMultiple userObject, User.schema.attributes
res = tv4.validateMultiple userObject, User.schema
return forms.applyErrorsToForm(@$el, res.errors) unless res.valid
window.tracker?.trackEvent 'Finished Signup'
@enableModalInProgress(@$el)

View file

@ -1,6 +1,6 @@
mongoose = require('mongoose')
plugins = require('../plugins/plugins')
jsonschema = require('./level_schema')
jsonschema = require('../../app/schemas/level_schema')
LevelSchema = new mongoose.Schema({
description: String

View file

@ -1,6 +1,6 @@
mongoose = require('mongoose')
plugins = require('../../plugins/plugins')
jsonschema = require('./level_component_schema')
jsonschema = require('../../../app/schemas/level_component_schema')
LevelComponentSchema = new mongoose.Schema {
description: String

View file

@ -3,7 +3,7 @@ Handler = require('../../commons/Handler')
LevelComponentHandler = class LevelComponentHandler extends Handler
modelClass: LevelComponent
jsonSchema: require './level_component_schema'
jsonSchema: require '../../../app/schemas/level_component_schema'
editableProperties: [
'system'
'description'

View file

@ -2,7 +2,7 @@
mongoose = require('mongoose')
plugins = require('../../plugins/plugins')
jsonschema = require('./level_feedback_schema')
jsonschema = require('../../../app/schemas/level_feedback_schema')
LevelFeedbackSchema = new mongoose.Schema({
created:

View file

@ -4,7 +4,7 @@ Handler = require('../../commons/Handler')
class LevelFeedbackHandler extends Handler
modelClass: LevelFeedback
editableProperties: ['rating', 'review', 'level', 'levelID', 'levelName']
jsonSchema: require './level_feedback_schema'
jsonSchema: require '../../../app/schemas/level_feedback_schema'
makeNewInstance: (req) ->
feedback = super(req)

View file

@ -8,7 +8,7 @@ mongoose = require('mongoose')
LevelHandler = class LevelHandler extends Handler
modelClass: Level
jsonSchema: require './level_schema'
jsonSchema: require '../../app/schemas/level_schema'
editableProperties: [
'description'
'documentation'

View file

@ -2,7 +2,7 @@
mongoose = require('mongoose')
plugins = require('../../plugins/plugins')
jsonschema = require('./level_session_schema')
jsonschema = require('../../../app/schemas/level_session_schema')
LevelSessionSchema = new mongoose.Schema({
created:

View file

@ -9,7 +9,7 @@ class LevelSessionHandler extends Handler
editableProperties: ['multiplayer', 'players', 'code', 'completed', 'state',
'levelName', 'creatorName', 'levelID', 'screenshot',
'chat', 'teamSpells', 'submitted', 'unsubscribed']
jsonSchema: require './level_session_schema'
jsonSchema: require '../../../app/schemas/level_session_schema'
getByRelationship: (req, res, args...) ->
return @getActiveSessions req, res if args.length is 2 and args[1] is 'active'

View file

@ -1,6 +1,6 @@
mongoose = require('mongoose')
plugins = require('../../plugins/plugins')
jsonschema = require('./level_system_schema')
jsonschema = require('../../../app/schemas/level_system_schema')
LevelSystemSchema = new mongoose.Schema {
description: String

View file

@ -13,7 +13,7 @@ LevelSystemHandler = class LevelSystemHandler extends Handler
'configSchema'
]
postEditableProperties: ['name']
jsonSchema: require './level_system_schema'
jsonSchema: require '../../../app/schemas/level_system_schema'
getEditableProperties: (req, document) ->
props = super(req, document)

View file

@ -3,7 +3,7 @@ Handler = require('../../commons/Handler')
ThangTypeHandler = class ThangTypeHandler extends Handler
modelClass: ThangType
jsonSchema: require './thang_type_schema'
jsonSchema: require '../../../app/schemas/thang_type_schema'
editableProperties: [
'name',
'raw',

View file

@ -1,6 +1,6 @@
Patch = require('./Patch')
Handler = require('../commons/Handler')
schema = require './patch_schema'
schema = require '../../app/schemas/patch_schema'
{handlers} = require '../commons/mapping'
mongoose = require('mongoose')
@ -8,7 +8,7 @@ PatchHandler = class PatchHandler extends Handler
modelClass: Patch
editableProperties: []
postEditableProperties: ['delta', 'target', 'commitMessage']
jsonSchema: require './patch_schema'
jsonSchema: require '../../app/schemas/patch_schema'
makeNewInstance: (req) ->
patch = super(req)

View file

@ -47,8 +47,8 @@ module.exports.setup = (app) ->
getSchema = (req, res, moduleName) ->
try
name = schemas[moduleName.replace '.', '_']
schema = require('../' + name)
name = moduleName.replace '.', '_'
schema = require('../../app/schemas/' + name + '_schema')
res.send(JSON.stringify(schema, null, '\t'))
res.end()

View file

@ -1,5 +1,5 @@
mongoose = require('mongoose')
jsonschema = require('./user_schema')
jsonschema = require('../../app/schemas/user_schema')
crypto = require('crypto')
{salt, isProduction} = require('../../server_config')
mail = require '../commons/mail'

View file

@ -1,4 +1,4 @@
schema = require './user_schema'
schema = require '../../app/schemas/user_schema'
crypto = require 'crypto'
request = require 'request'
User = require './User'