@roster-lock/shared 0.1.0
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/LICENSE.md +11 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/match-lock-file/config-types.js +3 -0
- package/dist/match-lock-file/config-types.js.map +1 -0
- package/dist/match-lock-file/index.js +19 -0
- package/dist/match-lock-file/index.js.map +1 -0
- package/dist/match-lock-file/match-config/index.js +18 -0
- package/dist/match-lock-file/match-config/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/draft/index.js +44 -0
- package/dist/match-lock-file/match-config/version-1/draft/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/draft/roster-piece-info.js +32 -0
- package/dist/match-lock-file/match-config/version-1/draft/roster-piece-info.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/draft/selection-script-info.js +13 -0
- package/dist/match-lock-file/match-config/version-1/draft/selection-script-info.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/index.js +22 -0
- package/dist/match-lock-file/match-config/version-1/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/index.js +37 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/keywords.js +43 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/keywords.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/index.js +7 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/officialSelections.js +41 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/officialSelections.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/index.js +20 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/keywords.js +31 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/keywords.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/schema.js +40 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/schema.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/index.js +17 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/keywords.js +16 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/keywords.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/index.js +19 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/error.js +25 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/error.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/index.js +33 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath-component.js +31 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath-component.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath.js +37 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/index.js +22 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/pathvariables.js +24 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/pathvariables.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/index.js +39 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/index.js +46 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/path-variables.js +23 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/path-variables.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/requirements.js +99 -0
- package/dist/match-lock-file/match-config/version-1/lock/engine/validate/piece/requirements.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/index.js +56 -0
- package/dist/match-lock-file/match-config/version-1/lock/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/caster-json-schema/index.js +87 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/caster-json-schema/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/index.js +19 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/validate/index.js +94 -0
- package/dist/match-lock-file/match-config/version-1/lock/piece-meta/validate/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/downloadableSources.js +18 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/downloadableSources.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/human.js +28 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/human.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/id.js +31 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/id.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/index.js +68 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/pathVariables.js +49 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/pathVariables.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/requiresPieces.js +62 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/requiresPieces.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/version.js +21 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/version.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/index.js +19 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/downloadable-source.js +10 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/downloadable-source.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/human.js +27 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/human.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/id.js +27 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/id.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/index.js +74 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/path-variables.js +31 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/path-variables.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/required-pieces.js +25 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/required-pieces.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/utils.js +23 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/utils.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/version.js +19 -0
- package/dist/match-lock-file/match-config/version-1/lock/rosters/validate/version.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/index.js +42 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/script.js +46 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/script.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/game-controlled.js +12 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/game-controlled.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/normal.js +49 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/normal.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/preselected.js +32 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/preselected.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/unselectable.js +12 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/unselectable.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/index.js +19 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/index.js +33 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/script.js +23 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/script.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/selections/normal.js +49 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/selections/normal.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/selections/preselected.js +14 -0
- package/dist/match-lock-file/match-config/version-1/lock/selection/validate/selections/preselected.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/file-paths.js +5 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/file-paths.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/index.js +23 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/keywords.js +29 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/keywords.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/schema.js +19 -0
- package/dist/match-lock-file/match-config/version-1/piece-info/schema.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/shared/Identity.js +15 -0
- package/dist/match-lock-file/match-config/version-1/shared/Identity.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/shared/SelectedPiece.js +38 -0
- package/dist/match-lock-file/match-config/version-1/shared/SelectedPiece.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/shared/count.js +48 -0
- package/dist/match-lock-file/match-config/version-1/shared/count.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/shared/index.js +25 -0
- package/dist/match-lock-file/match-config/version-1/shared/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/calculatePieceVersion.js +70 -0
- package/dist/match-lock-file/match-config/version-1/usage/calculatePieceVersion.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/empty-configs.js +49 -0
- package/dist/match-lock-file/match-config/version-1/usage/empty-configs.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/constants.js +8 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/constants.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/getAssetsOfFiles.js +75 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/getAssetsOfFiles.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/getMatchingAsset.js +28 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/getMatchingAsset.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/index.js +20 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/types.js +3 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/types.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/validateAssetFileCount.js +33 -0
- package/dist/match-lock-file/match-config/version-1/usage/files-and-assets/validateAssetFileCount.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/index.js +22 -0
- package/dist/match-lock-file/match-config/version-1/usage/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/SemVer.js +63 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/SemVer.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/diffLocks.js +51 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/diffLocks.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/index.js +19 -0
- package/dist/match-lock-file/match-config/version-1/usage/publish/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/constants.js +14 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/constants.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/ensure-pieces-are-in-roster.js +53 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/ensure-pieces-are-in-roster.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/handle-validation.js +49 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/handle-validation.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/index.js +68 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/game-controlled.js +38 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/game-controlled.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/cast-result.js +40 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/cast-result.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/index.js +78 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/index.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/validate-user-selection.js +43 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/validate-user-selection.js.map +1 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/preselected.js +26 -0
- package/dist/match-lock-file/match-config/version-1/usage/validate-select/selection-types/preselected.js.map +1 -0
- package/dist/match-lock-file/util-types/json-schema/JSONSchemaCaster.js +45 -0
- package/dist/match-lock-file/util-types/json-schema/JSONSchemaCaster.js.map +1 -0
- package/dist/match-lock-file/util-types/json-schema/defineKeyword.js +30 -0
- package/dist/match-lock-file/util-types/json-schema/defineKeyword.js.map +1 -0
- package/dist/match-lock-file/util-types/json-schema/index.js +21 -0
- package/dist/match-lock-file/util-types/json-schema/index.js.map +1 -0
- package/dist/match-lock-file/util-types/json-schema/safe-keyword.js +3 -0
- package/dist/match-lock-file/util-types/json-schema/safe-keyword.js.map +1 -0
- package/dist/match-lock-file/util-types/json-schema/schema-types.js +3 -0
- package/dist/match-lock-file/util-types/json-schema/schema-types.js.map +1 -0
- package/package.json +49 -0
- package/src/index.ts +3 -0
- package/src/match-lock-file/config-types.ts +10 -0
- package/src/match-lock-file/index.ts +4 -0
- package/src/match-lock-file/match-config/index.ts +2 -0
- package/src/match-lock-file/match-config/version-0/pieces/caster-runtypes/index.ts +99 -0
- package/src/match-lock-file/match-config/version-0/pieces/caster-runtypes/util-casters.ts +155 -0
- package/src/match-lock-file/match-config/version-0/pieces/index.ts +3 -0
- package/src/match-lock-file/match-config/version-0/pieces/types.ts +49 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/definition/assetCount.ts +33 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/definition/assetType.ts +22 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/definition/index.ts +30 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/definition/pathVariables.ts +39 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/index.ts +4 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/sha.ts +23 -0
- package/src/match-lock-file/match-config/version-0/pieces/validate/version.ts +66 -0
- package/src/match-lock-file/match-config/version-0/restriction/casters.ts +52 -0
- package/src/match-lock-file/match-config/version-0/restriction/index.ts +4 -0
- package/src/match-lock-file/match-config/version-0/restriction/types.ts +42 -0
- package/src/match-lock-file/match-config/version-0/restriction/validate/index.ts +15 -0
- package/src/match-lock-file/match-config/version-0/restriction/validate/piece/index.ts +46 -0
- package/src/match-lock-file/match-config/version-0/restriction/validate/sha.ts +19 -0
- package/src/match-lock-file/match-config/version-0/selection/casters.ts +105 -0
- package/src/match-lock-file/match-config/version-0/selection/validate/count.ts +16 -0
- package/src/match-lock-file/match-config/version-0/selection/validate/index.ts +40 -0
- package/src/match-lock-file/match-config/version-0/selection/validate/scriptMeta.ts +26 -0
- package/src/match-lock-file/match-config/version-1/draft/index.ts +52 -0
- package/src/match-lock-file/match-config/version-1/draft/roster-piece-info.ts +33 -0
- package/src/match-lock-file/match-config/version-1/draft/selection-script-info.ts +16 -0
- package/src/match-lock-file/match-config/version-1/index.ts +7 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/index.ts +46 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/asset/keywords.ts +48 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/index.ts +6 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/officialSelections.ts +42 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/index.ts +26 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/requirements/keywords.ts +34 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/schema.ts +47 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/index.ts +22 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/caster-json-schema/variables/keywords.ts +14 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/index.ts +3 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/constants.ts +7 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/error.ts +21 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/index.ts +18 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath-component.ts +41 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/filepath.ts +55 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/index.ts +21 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/glob/pathvariables.ts +28 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/assets/index.ts +46 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/index.ts +37 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/path-variables.ts +21 -0
- package/src/match-lock-file/match-config/version-1/lock/engine/validate/piece/requirements.ts +117 -0
- package/src/match-lock-file/match-config/version-1/lock/index.ts +51 -0
- package/src/match-lock-file/match-config/version-1/lock/piece-meta/caster-json-schema/index.ts +97 -0
- package/src/match-lock-file/match-config/version-1/lock/piece-meta/index.ts +3 -0
- package/src/match-lock-file/match-config/version-1/lock/piece-meta/validate/index.ts +114 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/downloadableSources.ts +25 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/human.ts +33 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/id.ts +33 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/index.ts +103 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/pathVariables.ts +59 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/requiresPieces.ts +71 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/caster-json-schema/version.ts +22 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/index.ts +3 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/downloadable-source.ts +9 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/human.ts +22 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/id.ts +20 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/index.ts +83 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/path-variables.ts +40 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/required-pieces.ts +30 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/utils.ts +17 -0
- package/src/match-lock-file/match-config/version-1/lock/rosters/validate/version.ts +22 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/index.ts +53 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/script.ts +54 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/game-controlled.ts +11 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/normal.ts +58 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/preselected.ts +37 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/caster-json-schema/selection-types/unselectable.ts +11 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/index.ts +3 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/validate/index.ts +37 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/validate/script.ts +28 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/validate/selections/normal.ts +69 -0
- package/src/match-lock-file/match-config/version-1/lock/selection/validate/selections/preselected.ts +18 -0
- package/src/match-lock-file/match-config/version-1/piece-info/file-paths.ts +2 -0
- package/src/match-lock-file/match-config/version-1/piece-info/index.ts +14 -0
- package/src/match-lock-file/match-config/version-1/piece-info/keywords.ts +39 -0
- package/src/match-lock-file/match-config/version-1/piece-info/schema.ts +29 -0
- package/src/match-lock-file/match-config/version-1/shared/Identity.ts +14 -0
- package/src/match-lock-file/match-config/version-1/shared/SelectedPiece.ts +49 -0
- package/src/match-lock-file/match-config/version-1/shared/count.ts +47 -0
- package/src/match-lock-file/match-config/version-1/shared/index.ts +9 -0
- package/src/match-lock-file/match-config/version-1/usage/calculatePieceVersion.ts +85 -0
- package/src/match-lock-file/match-config/version-1/usage/empty-configs.ts +61 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/constants.ts +6 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/getAssetsOfFiles.ts +88 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/getMatchingAsset.ts +42 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/index.ts +4 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/types.ts +5 -0
- package/src/match-lock-file/match-config/version-1/usage/files-and-assets/validateAssetFileCount.ts +34 -0
- package/src/match-lock-file/match-config/version-1/usage/index.ts +6 -0
- package/src/match-lock-file/match-config/version-1/usage/publish/SemVer.ts +67 -0
- package/src/match-lock-file/match-config/version-1/usage/publish/diffLocks.ts +66 -0
- package/src/match-lock-file/match-config/version-1/usage/publish/index.ts +2 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/constants.ts +9 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/ensure-pieces-are-in-roster.ts +61 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/handle-validation.ts +54 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/index.ts +98 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/game-controlled.ts +49 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/cast-result.ts +39 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/include-mandatory-require.ts +44 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/index.ts +101 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/validate-user-selection.ts +51 -0
- package/src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/preselected.ts +36 -0
- package/src/match-lock-file/util-types/json-schema/JSONSchemaCaster.ts +52 -0
- package/src/match-lock-file/util-types/json-schema/checkVersion.ts +9 -0
- package/src/match-lock-file/util-types/json-schema/defineKeyword.ts +50 -0
- package/src/match-lock-file/util-types/json-schema/index.ts +4 -0
- package/src/match-lock-file/util-types/json-schema/safe-keyword.ts +27 -0
- package/src/match-lock-file/util-types/json-schema/schema-types.ts +5 -0
- package/tests/engine/assets.spec.ts +147 -0
- package/tests/engine/official-selections.spec.ts +67 -0
- package/tests/engine/requirements.spec.ts +43 -0
- package/tests/piece-info/cast.spec.ts +20 -0
- package/tests/piece-info/rosterlock.piece-info.json +15 -0
- package/tests/piece-meta/cast.spec.ts +60 -0
- package/tests/rosters/path-variables.spec.ts +52 -0
- package/tests/selection/cast-result.spec.ts +72 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
4
|
+
|
|
5
|
+
import { ROSTERLOCK_V1_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/lock/index.js";
|
|
6
|
+
import { EMPTY_ROSTER_LOCK } from "../../src/match-lock-file/match-config/version-1/usage/empty-configs.js";
|
|
7
|
+
import { getMatchingAssetsForFile } from "../../src/match-lock-file/match-config/version-1/usage/files-and-assets/getMatchingAsset.js";
|
|
8
|
+
import { PieceDefinition } from "../../src/match-lock-file/match-config/version-1/usage/files-and-assets/types.js";
|
|
9
|
+
|
|
10
|
+
function buildLockWithAssetPiece(): RosterLockV1Config {
|
|
11
|
+
const lock = cloneJSON(EMPTY_ROSTER_LOCK);
|
|
12
|
+
lock.engine.pieceDefinitions["character"] = {
|
|
13
|
+
selectionStrategy: "mandatory",
|
|
14
|
+
requires: [],
|
|
15
|
+
pathVariables: ["skin"],
|
|
16
|
+
assets: [{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] }],
|
|
17
|
+
};
|
|
18
|
+
lock.rosters["character"] = [];
|
|
19
|
+
return lock;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("engine piece assets validation", () => {
|
|
23
|
+
it("accepts a piece whose asset names are unique and globs use declared path variables", () => {
|
|
24
|
+
const lock = buildLockWithAssetPiece();
|
|
25
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("rejects a piece with a duplicate asset name", () => {
|
|
29
|
+
const lock = buildLockWithAssetPiece();
|
|
30
|
+
lock.engine.pieceDefinitions["character"].assets.push(
|
|
31
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["other/*.png"] }
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
35
|
+
expect(result.valid).toBe(false);
|
|
36
|
+
if(result.valid) return;
|
|
37
|
+
expect(result.error.some((e) => /duplicate name/i.test(e.message ?? ""))).toBe(true);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("rejects an asset glob referencing a path variable the piece type doesn't declare", () => {
|
|
41
|
+
const lock = buildLockWithAssetPiece();
|
|
42
|
+
lock.engine.pieceDefinitions["character"].assets[0].glob = ["<region>/*.png"];
|
|
43
|
+
|
|
44
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
45
|
+
expect(result.valid).toBe(false);
|
|
46
|
+
if(result.valid) return;
|
|
47
|
+
expect(result.error.some((e) => /undefined path variable/i.test(e.message ?? ""))).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
function buildPieceDefinition(
|
|
52
|
+
pathVariables: PieceDefinition["pathVariables"],
|
|
53
|
+
assets: PieceDefinition["assets"],
|
|
54
|
+
): PieceDefinition {
|
|
55
|
+
return { selectionStrategy: "mandatory", requires: [], pathVariables, assets };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
describe("getMatchingAssetsForFile path variables and globs", () => {
|
|
59
|
+
it("matches a glob once its path variable is substituted with the roster's value", () => {
|
|
60
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
61
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
62
|
+
]);
|
|
63
|
+
const matches = getMatchingAssetsForFile(piece, { skin: "blue" }, "blue/idle.png");
|
|
64
|
+
expect(matches.map((a) => a.name)).toEqual(["sprite"]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("does not match when the file's path segment differs from the path variable's value", () => {
|
|
68
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
69
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
70
|
+
]);
|
|
71
|
+
expect(getMatchingAssetsForFile(piece, { skin: "blue" }, "red/idle.png")).toEqual([]);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("matches a path variable used inside a filename, not just a directory segment", () => {
|
|
75
|
+
// Ikemen-Go style character defs, e.g. "<character>.def"
|
|
76
|
+
const piece = buildPieceDefinition(["character"], [
|
|
77
|
+
{ name: "def-file", classification: "logic", count: 1, glob: ["<character>.def"] },
|
|
78
|
+
]);
|
|
79
|
+
expect(getMatchingAssetsForFile(piece, { character: "kfm" }, "kfm.def").map((a) => a.name))
|
|
80
|
+
.toEqual(["def-file"]);
|
|
81
|
+
expect(getMatchingAssetsForFile(piece, { character: "kfm" }, "ryu.def")).toEqual([]);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("resolves multiple path variables combined with a globstar across nested directories", () => {
|
|
85
|
+
const piece = buildPieceDefinition(["character", "skin"], [
|
|
86
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<character>/<skin>/**/*.png"] },
|
|
87
|
+
]);
|
|
88
|
+
const pathVariables = { character: "kfm", skin: "default" };
|
|
89
|
+
expect(getMatchingAssetsForFile(piece, pathVariables, "kfm/default/stance/1.png").length).toBe(1);
|
|
90
|
+
expect(getMatchingAssetsForFile(piece, pathVariables, "kfm/other/stance/1.png")).toEqual([]);
|
|
91
|
+
expect(getMatchingAssetsForFile(piece, pathVariables, "other/default/stance/1.png")).toEqual([]);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("matches an asset if any of its globs match, mixing a literal glob with a path-variable glob", () => {
|
|
95
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
96
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["portrait.png", "<skin>/*.png"] },
|
|
97
|
+
]);
|
|
98
|
+
expect(getMatchingAssetsForFile(piece, { skin: "blue" }, "portrait.png").map((a) => a.name))
|
|
99
|
+
.toEqual(["sprite"]);
|
|
100
|
+
expect(getMatchingAssetsForFile(piece, { skin: "blue" }, "blue/idle.png").map((a) => a.name))
|
|
101
|
+
.toEqual(["sprite"]);
|
|
102
|
+
expect(getMatchingAssetsForFile(piece, { skin: "blue" }, "red/idle.png")).toEqual([]);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("matches via exact equality when the glob has no wildcard characters", () => {
|
|
106
|
+
const piece = buildPieceDefinition([], [
|
|
107
|
+
{ name: "portrait", classification: "media", count: 1, glob: ["assets/portrait.png"] },
|
|
108
|
+
]);
|
|
109
|
+
expect(getMatchingAssetsForFile(piece, {}, "assets/portrait.png").map((a) => a.name))
|
|
110
|
+
.toEqual(["portrait"]);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("allows path variable values containing spaces", () => {
|
|
114
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
115
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
116
|
+
]);
|
|
117
|
+
expect(getMatchingAssetsForFile(piece, { skin: "light blue" }, "light blue/idle.png").map((a) => a.name))
|
|
118
|
+
.toEqual(["sprite"]);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it("returns every asset whose glob matches, when globs overlap", () => {
|
|
122
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
123
|
+
{ name: "any-png", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
124
|
+
{ name: "idle-png", classification: "media", count: 1, glob: ["<skin>/idle.png"] },
|
|
125
|
+
]);
|
|
126
|
+
const matches = getMatchingAssetsForFile(piece, { skin: "blue" }, "blue/idle.png");
|
|
127
|
+
expect(matches.map((a) => a.name).sort()).toEqual(["any-png", "idle-png"]);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("throws instead of matching when a path variable value contains disallowed characters", () => {
|
|
131
|
+
// Guards against path variable values being used to smuggle glob/traversal syntax into the pattern
|
|
132
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
133
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
134
|
+
]);
|
|
135
|
+
expect(() => getMatchingAssetsForFile(piece, { skin: "../etc" }, "../etc/idle.png"))
|
|
136
|
+
.toThrow(/invalid characters/i);
|
|
137
|
+
expect(() => getMatchingAssetsForFile(piece, { skin: "*" }, "*/idle.png"))
|
|
138
|
+
.toThrow(/invalid characters/i);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("throws when a path variable value is empty", () => {
|
|
142
|
+
const piece = buildPieceDefinition(["skin"], [
|
|
143
|
+
{ name: "sprite", classification: "media", count: 1, glob: ["<skin>/*.png"] },
|
|
144
|
+
]);
|
|
145
|
+
expect(() => getMatchingAssetsForFile(piece, { skin: "" }, "idle.png")).toThrow(/too short/i);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
4
|
+
|
|
5
|
+
import { ROSTERLOCK_V1_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/lock/index.js";
|
|
6
|
+
import { EMPTY_ROSTER_LOCK } from "../../src/match-lock-file/match-config/version-1/usage/empty-configs.js";
|
|
7
|
+
|
|
8
|
+
function buildLock(): RosterLockV1Config {
|
|
9
|
+
return cloneJSON(EMPTY_ROSTER_LOCK);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe("engine officialSelections validation", () => {
|
|
13
|
+
it("is optional - a lock with no officialSelections is still valid", () => {
|
|
14
|
+
const lock = buildLock();
|
|
15
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("accepts a list of tagged, unique, well-formed hashes", () => {
|
|
19
|
+
const lock = buildLock();
|
|
20
|
+
lock.engine.officialSelections = [
|
|
21
|
+
{ tag: "3v3-tag-team", hash: "a".repeat(64) },
|
|
22
|
+
{ tag: "1v1", hash: "b".repeat(64) },
|
|
23
|
+
];
|
|
24
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("rejects a hash that isn't a 64-char hex string", () => {
|
|
28
|
+
const lock = buildLock();
|
|
29
|
+
lock.engine.officialSelections = [{ tag: "1v1", hash: "not-a-hash" }];
|
|
30
|
+
|
|
31
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
32
|
+
expect(result.valid).toBe(false);
|
|
33
|
+
if(result.valid) return;
|
|
34
|
+
expect(result.error.some((e) => /not a valid SHA-256/i.test(e.message ?? ""))).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("rejects two entries sharing the same hash, even under different tags", () => {
|
|
38
|
+
const lock = buildLock();
|
|
39
|
+
const hash = "a".repeat(64);
|
|
40
|
+
lock.engine.officialSelections = [
|
|
41
|
+
{ tag: "3v3-tag-team", hash },
|
|
42
|
+
{ tag: "3v3-tag-team-v2", hash },
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
46
|
+
expect(result.valid).toBe(false);
|
|
47
|
+
if(result.valid) return;
|
|
48
|
+
expect(result.error.some((e) => /duplicate official selection hash/i.test(e.message ?? ""))).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("allows two entries sharing the same tag with different hashes (a revision under the same UI screen)", () => {
|
|
52
|
+
const lock = buildLock();
|
|
53
|
+
lock.engine.officialSelections = [
|
|
54
|
+
{ tag: "3v3-tag-team", hash: "a".repeat(64) },
|
|
55
|
+
{ tag: "3v3-tag-team", hash: "b".repeat(64) },
|
|
56
|
+
];
|
|
57
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("rejects an entry missing a tag", () => {
|
|
61
|
+
const lock = buildLock();
|
|
62
|
+
lock.engine.officialSelections = [{ hash: "a".repeat(64) } as any];
|
|
63
|
+
|
|
64
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
65
|
+
expect(result.valid).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
4
|
+
|
|
5
|
+
import { ROSTERLOCK_V1_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/lock/index.js";
|
|
6
|
+
import { EMPTY_ROSTER_LOCK } from "../../src/match-lock-file/match-config/version-1/usage/empty-configs.js";
|
|
7
|
+
|
|
8
|
+
function buildLockWithRequiresPiece(): RosterLockV1Config {
|
|
9
|
+
const lock = cloneJSON(EMPTY_ROSTER_LOCK);
|
|
10
|
+
lock.engine.pieceDefinitions["character"] = {
|
|
11
|
+
selectionStrategy: "mandatory",
|
|
12
|
+
requires: ["hat"],
|
|
13
|
+
pathVariables: [],
|
|
14
|
+
assets: [],
|
|
15
|
+
};
|
|
16
|
+
lock.engine.pieceDefinitions["hat"] = {
|
|
17
|
+
selectionStrategy: "on demand",
|
|
18
|
+
requires: [],
|
|
19
|
+
pathVariables: [],
|
|
20
|
+
assets: [],
|
|
21
|
+
};
|
|
22
|
+
lock.rosters["character"] = [];
|
|
23
|
+
lock.rosters["hat"] = [];
|
|
24
|
+
return lock;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe("engine piece requirements validation", () => {
|
|
28
|
+
it("accepts a piece that requires an on-demand piece with no cycle", () => {
|
|
29
|
+
const lock = buildLockWithRequiresPiece();
|
|
30
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("rejects piece types whose requirements form a cycle", () => {
|
|
34
|
+
const lock = buildLockWithRequiresPiece();
|
|
35
|
+
lock.engine.pieceDefinitions["character"].selectionStrategy = "on demand";
|
|
36
|
+
lock.engine.pieceDefinitions["hat"].requires = ["character"];
|
|
37
|
+
|
|
38
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
39
|
+
expect(result.valid).toBe(false);
|
|
40
|
+
if(result.valid) return;
|
|
41
|
+
expect(result.error.some((e) => /form a cycle/i.test(e.message ?? ""))).toBe(true);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { ROSTERLOCK_V1_PIECEINFO_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/piece-info/index.js";
|
|
4
|
+
|
|
5
|
+
import pieceInfoJson from "./rosterlock.piece-info.json";
|
|
6
|
+
|
|
7
|
+
describe("ROSTERLOCK_V1_PIECEINFO_CASTER_JSONSCHEMA", () => {
|
|
8
|
+
it("casts a valid piece-info JSON file", () => {
|
|
9
|
+
const result = ROSTERLOCK_V1_PIECEINFO_CASTER_JSONSCHEMA.safeCast(pieceInfoJson);
|
|
10
|
+
expect(result.valid).toBe(true);
|
|
11
|
+
if (!result.valid) return;
|
|
12
|
+
expect(result.value.configIdentity.namespace).toBe("roster-lock");
|
|
13
|
+
expect(result.value.configIdentity.purpose).toBe("piece-info");
|
|
14
|
+
expect(result.value.configIdentity.version).toBe(1);
|
|
15
|
+
expect(result.value.humanInfo.name).toBe("Blue");
|
|
16
|
+
expect(result.value.humanInfo.author).toBe("match-lock");
|
|
17
|
+
expect(result.value.downloadSources).toEqual(["http://localhost:7342/pieces/character/blue.tar"]);
|
|
18
|
+
expect(result.value.pathVariables).toEqual({});
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configIdentity": {
|
|
3
|
+
"namespace": "roster-lock",
|
|
4
|
+
"purpose": "piece-info",
|
|
5
|
+
"version": 1
|
|
6
|
+
},
|
|
7
|
+
"humanInfo": {
|
|
8
|
+
"name": "Blue",
|
|
9
|
+
"author": "match-lock",
|
|
10
|
+
"url": "http://localhost:7342/pieces/character/blue"
|
|
11
|
+
},
|
|
12
|
+
"downloadSources": ["http://localhost:7342/pieces/character/blue.tar"],
|
|
13
|
+
"pathVariables": {}
|
|
14
|
+
}
|
|
15
|
+
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
4
|
+
|
|
5
|
+
import { ROSTERLOCK_V1_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/lock/index.js";
|
|
6
|
+
import { EMPTY_ROSTER_LOCK } from "../../src/match-lock-file/match-config/version-1/usage/empty-configs.js";
|
|
7
|
+
|
|
8
|
+
function buildLockWithPieceMeta(): RosterLockV1Config {
|
|
9
|
+
const lock = cloneJSON(EMPTY_ROSTER_LOCK);
|
|
10
|
+
lock.engine.pieceDefinitions["character"] = {
|
|
11
|
+
selectionStrategy: "mandatory",
|
|
12
|
+
requires: [],
|
|
13
|
+
pathVariables: [],
|
|
14
|
+
assets: [],
|
|
15
|
+
};
|
|
16
|
+
lock.rosters["character"] = [{
|
|
17
|
+
id: "@author/blue",
|
|
18
|
+
version: { logic: "a".repeat(64), media: "b".repeat(64), docs: "c".repeat(64) },
|
|
19
|
+
humanInfo: { name: "Blue", author: "author", url: "https://example.com/blue" },
|
|
20
|
+
downloadSources: ["https://example.com/blue.tar"],
|
|
21
|
+
pathVariables: {},
|
|
22
|
+
requiredPieces: {},
|
|
23
|
+
}];
|
|
24
|
+
lock.selection.piece["character"] = {
|
|
25
|
+
type: "unselectable",
|
|
26
|
+
};
|
|
27
|
+
lock.pieceMeta["character"] = {
|
|
28
|
+
schema: { power: "number" },
|
|
29
|
+
defaultMeta: { power: 1 },
|
|
30
|
+
values: { "@author/blue": { power: 5 } },
|
|
31
|
+
};
|
|
32
|
+
return lock;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
describe("piece meta validation", () => {
|
|
36
|
+
it("accepts default meta and per-piece meta that match the declared schema", () => {
|
|
37
|
+
const lock = buildLockWithPieceMeta();
|
|
38
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("rejects default meta missing a required schema key", () => {
|
|
42
|
+
const lock = buildLockWithPieceMeta();
|
|
43
|
+
lock.pieceMeta["character"].defaultMeta = {};
|
|
44
|
+
|
|
45
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
46
|
+
expect(result.valid).toBe(false);
|
|
47
|
+
if(result.valid) return;
|
|
48
|
+
expect(result.error.some((e) => /must have all required keys/i.test(e.message ?? ""))).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("rejects per-piece meta for a piece that isn't in the roster", () => {
|
|
52
|
+
const lock = buildLockWithPieceMeta();
|
|
53
|
+
lock.pieceMeta["character"].values = { "@author/missing": { power: 2 } };
|
|
54
|
+
|
|
55
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
56
|
+
expect(result.valid).toBe(false);
|
|
57
|
+
if(result.valid) return;
|
|
58
|
+
expect(result.error.some((e) => /not in the roster/i.test(e.message ?? ""))).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
4
|
+
|
|
5
|
+
import { ROSTERLOCK_V1_CASTER_JSONSCHEMA } from "../../src/match-lock-file/match-config/version-1/lock/index.js";
|
|
6
|
+
import { EMPTY_ROSTER_LOCK } from "../../src/match-lock-file/match-config/version-1/usage/empty-configs.js";
|
|
7
|
+
|
|
8
|
+
function buildLockWithPathVariablePiece(): RosterLockV1Config {
|
|
9
|
+
const lock = cloneJSON(EMPTY_ROSTER_LOCK);
|
|
10
|
+
lock.engine.pieceDefinitions["character"] = {
|
|
11
|
+
selectionStrategy: "mandatory",
|
|
12
|
+
requires: [],
|
|
13
|
+
pathVariables: ["skin"],
|
|
14
|
+
assets: [{ name: "sprite", classification: "media", count: 1, glob: ["{skin}/*.png"] }],
|
|
15
|
+
};
|
|
16
|
+
lock.rosters["character"] = [{
|
|
17
|
+
id: "@author/blue",
|
|
18
|
+
version: { logic: "a".repeat(64), media: "b".repeat(64), docs: "c".repeat(64) },
|
|
19
|
+
humanInfo: { name: "Blue", author: "author", url: "https://example.com/blue" },
|
|
20
|
+
downloadSources: ["https://example.com/blue.tar"],
|
|
21
|
+
pathVariables: { skin: "blue" },
|
|
22
|
+
requiredPieces: {},
|
|
23
|
+
}];
|
|
24
|
+
return lock;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
describe("roster piece pathVariables validation", () => {
|
|
28
|
+
it("accepts a piece whose pathVariables match the piece type's declared names", () => {
|
|
29
|
+
const lock = buildLockWithPathVariablePiece();
|
|
30
|
+
expect(() => ROSTERLOCK_V1_CASTER_JSONSCHEMA.cast(lock)).not.toThrow();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("rejects a piece missing a required path variable", () => {
|
|
34
|
+
const lock = buildLockWithPathVariablePiece();
|
|
35
|
+
lock.rosters["character"][0].pathVariables = {};
|
|
36
|
+
|
|
37
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
38
|
+
expect(result.valid).toBe(false);
|
|
39
|
+
if(result.valid) return;
|
|
40
|
+
expect(result.error.some((e) => /missing value for path variable/i.test(e.message ?? ""))).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("rejects a piece with a path variable name the piece type doesn't declare", () => {
|
|
44
|
+
const lock = buildLockWithPathVariablePiece();
|
|
45
|
+
lock.rosters["character"][0].pathVariables = { skin: "blue", region: "eu" };
|
|
46
|
+
|
|
47
|
+
const result = ROSTERLOCK_V1_CASTER_JSONSCHEMA.safeCast(lock);
|
|
48
|
+
expect(result.valid).toBe(false);
|
|
49
|
+
if(result.valid) return;
|
|
50
|
+
expect(result.error.some((e) => /does not have path variable/i.test(e.message ?? ""))).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { castSharedResult, castPersonalResult } from "../../src/match-lock-file/match-config/version-1/usage/validate-select/selection-types/normal/cast-result.js";
|
|
4
|
+
|
|
5
|
+
function validPiece() {
|
|
6
|
+
return {
|
|
7
|
+
id: "@author/blue",
|
|
8
|
+
required: {
|
|
9
|
+
character: {
|
|
10
|
+
mandatory: [
|
|
11
|
+
{
|
|
12
|
+
id: "@author/red",
|
|
13
|
+
required: {},
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
selectable: [],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("castSharedResult", () => {
|
|
23
|
+
it("accepts a SelectedPiece with required keyed by piece type", () => {
|
|
24
|
+
const value = [validPiece()];
|
|
25
|
+
expect(() => castSharedResult(value)).not.toThrow();
|
|
26
|
+
expect(castSharedResult(value)).toEqual(value);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("accepts a piece with no required entries", () => {
|
|
30
|
+
const value = [{ id: "@author/blue", required: {} }];
|
|
31
|
+
expect(() => castSharedResult(value)).not.toThrow();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("rejects required.mandatory/selectable placed directly on the piece instead of under a piece-type key", () => {
|
|
35
|
+
const value = [{
|
|
36
|
+
id: "@author/blue",
|
|
37
|
+
required: { mandatory: [], selectable: [] },
|
|
38
|
+
}];
|
|
39
|
+
expect(() => castSharedResult(value)).toThrow();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("rejects a piece missing an id", () => {
|
|
43
|
+
const value = [{ required: {} }];
|
|
44
|
+
expect(() => castSharedResult(value)).toThrow();
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("rejects a piece-type entry missing mandatory/selectable", () => {
|
|
48
|
+
const value = [{
|
|
49
|
+
id: "@author/blue",
|
|
50
|
+
required: { character: { mandatory: [] } },
|
|
51
|
+
}];
|
|
52
|
+
expect(() => castSharedResult(value)).toThrow();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("rejects unknown properties on a piece", () => {
|
|
56
|
+
const value = [{ id: "@author/blue", required: {}, extra: true }];
|
|
57
|
+
expect(() => castSharedResult(value)).toThrow();
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("castPersonalResult", () => {
|
|
62
|
+
it("accepts a map of user id to selected pieces", () => {
|
|
63
|
+
const value = { user1: [validPiece()] };
|
|
64
|
+
expect(() => castPersonalResult(value)).not.toThrow();
|
|
65
|
+
expect(castPersonalResult(value)).toEqual(value);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("rejects a user's selection containing an invalid piece", () => {
|
|
69
|
+
const value = { user1: [{ id: "@author/blue", required: { mandatory: [], selectable: [] } }] };
|
|
70
|
+
expect(() => castPersonalResult(value)).toThrow();
|
|
71
|
+
});
|
|
72
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"moduleResolution": "nodenext",
|
|
6
|
+
"types": ["node"],
|
|
7
|
+
"lib": ["es2022"],
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"outDir": "./dist",
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"removeComments": true,
|
|
15
|
+
"noImplicitAny": true
|
|
16
|
+
},
|
|
17
|
+
"files": ["src/index.ts"],
|
|
18
|
+
"include": ["./typings", "./types", "**/*.test.ts"],
|
|
19
|
+
"exclude": ["node_modules", "**/*.spec.ts"]
|
|
20
|
+
}
|