@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,85 @@
|
|
|
1
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
2
|
+
|
|
3
|
+
type PieceDefinition = RosterLockV1Config["engine"]["pieceDefinitions"][string];
|
|
4
|
+
type EngineAssetDefinition = PieceDefinition["assets"][number];
|
|
5
|
+
|
|
6
|
+
type FileWithSha = { path: string, asset: EngineAssetDefinition, sha: string }
|
|
7
|
+
type FileGetter = (path: string) => Promise<{ byteSize: number, stream: AsyncIterable<Uint8Array> }>
|
|
8
|
+
type ProgressListener = (progress: { file: string, current: number, total: number }) => any
|
|
9
|
+
export async function calculatePieceVersion(
|
|
10
|
+
files: Map<string, { assets: Array<EngineAssetDefinition> }>,
|
|
11
|
+
getFile: FileGetter,
|
|
12
|
+
onProgress?: ProgressListener
|
|
13
|
+
){
|
|
14
|
+
const logicFiles: Array<FileWithSha> = [];
|
|
15
|
+
const mediaFiles: Array<FileWithSha> = [];
|
|
16
|
+
const docFiles: Array<FileWithSha> = [];
|
|
17
|
+
|
|
18
|
+
await Promise.all(Array.from(files.entries()).map(async ([relativePath, { assets }]) => {
|
|
19
|
+
const sha = await getHashFromFile(relativePath, getFile, onProgress);
|
|
20
|
+
const asset = assets[0];
|
|
21
|
+
if(!asset) throw new Error(`No asset found for ${relativePath}`);
|
|
22
|
+
switch(asset.classification){
|
|
23
|
+
case "logic": logicFiles.push({ path: relativePath, asset, sha }); break;
|
|
24
|
+
case "media": mediaFiles.push({ path: relativePath, asset, sha }); break;
|
|
25
|
+
case "doc": docFiles.push({ path: relativePath, asset, sha }); break;
|
|
26
|
+
default: throw new Error(`Unknown asset type ${asset.classification}`);
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
logic: await calculateComnbinedHash(logicFiles.sort(shaSort)),
|
|
32
|
+
media: await calculateComnbinedHash(mediaFiles.sort(shaSort)),
|
|
33
|
+
docs: await calculateComnbinedHash(docFiles.sort(shaSort)),
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function shaSort(a: FileWithSha, b: FileWithSha){
|
|
38
|
+
return a.sha.localeCompare(b.sha);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function getHashFromFile(
|
|
42
|
+
file: string, getFile: FileGetter, onProgress?: ProgressListener
|
|
43
|
+
){
|
|
44
|
+
try {
|
|
45
|
+
const { stream, byteSize } = await getFile(file);
|
|
46
|
+
const buffer = new Uint8Array(byteSize);
|
|
47
|
+
let consumed = 0;
|
|
48
|
+
for await (const chunk of stream){
|
|
49
|
+
buffer.set(chunk, consumed);
|
|
50
|
+
consumed += chunk.byteLength;
|
|
51
|
+
onProgress && onProgress({ file, current: consumed, total: byteSize });
|
|
52
|
+
}
|
|
53
|
+
return toHex(await crypto.subtle.digest("SHA-256", buffer));
|
|
54
|
+
}catch(e){
|
|
55
|
+
throw new Error("Failed to calculate Hash from file")
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
async function calculateComnbinedHash(files: Array<FileWithSha>){
|
|
61
|
+
if (files.length === 0) {
|
|
62
|
+
return toHex(await crypto.subtle.digest("SHA-256", new Uint8Array(0)));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create our array with expected length ahead of time
|
|
66
|
+
const buffer = new Uint8Array(files.length * 32);
|
|
67
|
+
let offset = 0;
|
|
68
|
+
for(const { sha } of files){
|
|
69
|
+
for (let i = 0; i < sha.length; i += 2) {
|
|
70
|
+
// For each 2 characters
|
|
71
|
+
// Try to parse those two chararacters as if it were a hex value
|
|
72
|
+
const byte = Number.parseInt(sha.substring(i, i + 2), 16)
|
|
73
|
+
// If parsing failed, we failed
|
|
74
|
+
if(Number.isNaN(byte)) throw new Error(`Invalid SHA: ${sha}`);
|
|
75
|
+
// If we're ok, we set the byte on the offset directly
|
|
76
|
+
buffer[offset++] = byte;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return toHex(await crypto.subtle.digest("SHA-256", buffer));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function toHex(buffer: ArrayBuffer): string {
|
|
83
|
+
return Array.from(new Uint8Array(buffer)).map(b => b.toString(16).padStart(2, "0")).join("");
|
|
84
|
+
}
|
|
85
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { RosterLockV1Config, RosterLockV1Draft } from "@roster-lock/types";
|
|
2
|
+
import { cloneJSON } from "@roster-lock/utils";
|
|
3
|
+
|
|
4
|
+
export const EMPTY_ROSTER_LOCK: RosterLockV1Config = {
|
|
5
|
+
configIdentity: { namespace: "roster-lock", purpose: "lock", version: 1 },
|
|
6
|
+
author: "",
|
|
7
|
+
title: "",
|
|
8
|
+
version: "0.0.0",
|
|
9
|
+
engine: { name: "", version: "", pieceDefinitions: {} },
|
|
10
|
+
rosters: {},
|
|
11
|
+
selection: { piece: {}, globalValidation: [], scriptDictionary: {}, },
|
|
12
|
+
pieceMeta: {},
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const EMPTY_ROSTER_DRAFT: RosterLockV1Draft = {
|
|
16
|
+
configIdentity: { namespace: "roster-lock", purpose: "draft", version: 1 },
|
|
17
|
+
previousLock: cloneJSON(EMPTY_ROSTER_LOCK),
|
|
18
|
+
stagedLock: cloneJSON(EMPTY_ROSTER_LOCK),
|
|
19
|
+
draft: {
|
|
20
|
+
rosterPieceInfo: {},
|
|
21
|
+
selectionScriptInfo: {},
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
import {
|
|
26
|
+
SelectionGameControlledConfig,
|
|
27
|
+
SelectionNormalConfig,
|
|
28
|
+
SelectionPreselectedConfig,
|
|
29
|
+
SelectionUnselectableConfig,
|
|
30
|
+
SelectionPieceMeta,
|
|
31
|
+
JSONShallowObject,
|
|
32
|
+
} from "@roster-lock/types";
|
|
33
|
+
export const EMPTY_ROSTER_GAME_SELECTION: SelectionGameControlledConfig = {
|
|
34
|
+
type: "game-controlled",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const EMPTY_ROSTER_NORMAL_SELECTION: SelectionNormalConfig = {
|
|
38
|
+
type: "normal",
|
|
39
|
+
validation: {
|
|
40
|
+
count: "*",
|
|
41
|
+
unique: false,
|
|
42
|
+
banList: [],
|
|
43
|
+
customValidation: []
|
|
44
|
+
},
|
|
45
|
+
mergeAlgorithm: void 0
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const EMPTY_ROSTER_PRESELECTED_SELECTION: SelectionPreselectedConfig = {
|
|
49
|
+
type: "preselected",
|
|
50
|
+
pieces: []
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const EMPTY_ROSTER_UNSELECTABLE_SELECTION: SelectionUnselectableConfig = {
|
|
54
|
+
type: "unselectable",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const EMPTY_PIECE_META: SelectionPieceMeta<JSONShallowObject> = {
|
|
58
|
+
schema: {},
|
|
59
|
+
defaultMeta: {},
|
|
60
|
+
values: {},
|
|
61
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { FILES_TO_IGNORE } from "./constants";
|
|
2
|
+
|
|
3
|
+
import { getMatchingAssetsForFile } from "./getMatchingAsset";
|
|
4
|
+
|
|
5
|
+
import { PieceDefinition, EngineAssetDefinition } from "./types";
|
|
6
|
+
|
|
7
|
+
export { getMatchingAssetsForFile };
|
|
8
|
+
|
|
9
|
+
export async function getAssetsOfFiles(
|
|
10
|
+
files: Iterable<string> | AsyncIterable<string>,
|
|
11
|
+
pathVariables: Record<string, string>,
|
|
12
|
+
pieceDefinition: PieceDefinition,
|
|
13
|
+
): Promise<{
|
|
14
|
+
assetsWithFiles: Map<string, { asset: EngineAssetDefinition, files: Array<string> }>
|
|
15
|
+
filesWithAssets: Map<string, { assets: Array<EngineAssetDefinition> }>
|
|
16
|
+
}>{
|
|
17
|
+
const assetCounts = new Map<string, { files: Array<string>, asset: EngineAssetDefinition }>();
|
|
18
|
+
const fileCounts = new Map<string, { assets: Array<EngineAssetDefinition> }>();
|
|
19
|
+
for await (const filePath of files){
|
|
20
|
+
if(FILES_TO_IGNORE.includes(filePath)) continue;
|
|
21
|
+
|
|
22
|
+
const assetMatching = getMatchingAssetsForFile(pieceDefinition, pathVariables, filePath);
|
|
23
|
+
const asset = assetMatching[0];
|
|
24
|
+
if(!asset){
|
|
25
|
+
// Error: File doesn't match any assets
|
|
26
|
+
fileCounts.set(filePath, { assets: [] });
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if(assetMatching.length > 1){
|
|
30
|
+
// Warning: File matches multiple assets
|
|
31
|
+
}
|
|
32
|
+
const currentCount = ((): { files: Array<string>, asset: EngineAssetDefinition } =>{
|
|
33
|
+
const currentCount = assetCounts.get(asset.name);
|
|
34
|
+
if(currentCount) return currentCount;
|
|
35
|
+
const newCount = { files: [], asset: asset };
|
|
36
|
+
assetCounts.set(asset.name, newCount);
|
|
37
|
+
return newCount;
|
|
38
|
+
})();
|
|
39
|
+
|
|
40
|
+
currentCount.files.push(filePath);
|
|
41
|
+
fileCounts.set(filePath, { assets: assetMatching });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for(const asset of pieceDefinition.assets){
|
|
45
|
+
const currentCountInfo = assetCounts.get(asset.name);
|
|
46
|
+
if(!currentCountInfo){
|
|
47
|
+
// Error: Asset has no files
|
|
48
|
+
assetCounts.set(asset.name, { files: [], asset });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return { filesWithAssets: fileCounts, assetsWithFiles: assetCounts };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
import { isValidAssetFileCount, validateAssetFileCount } from "./validateAssetFileCount";
|
|
56
|
+
export function collectAssetFileErrors(
|
|
57
|
+
{ assetsWithFiles, filesWithAssets }: Awaited<ReturnType<typeof getAssetsOfFiles>>
|
|
58
|
+
){
|
|
59
|
+
const errors: Array<{ type: "asset" | "file", id: string, message: string }> = [];
|
|
60
|
+
for(const [assetName, { asset, files }] of assetsWithFiles){
|
|
61
|
+
try {
|
|
62
|
+
if(files.length === 0 && !isValidAssetFileCount(asset.count, 0)){
|
|
63
|
+
errors.push({
|
|
64
|
+
type: "asset",
|
|
65
|
+
id: assetName,
|
|
66
|
+
message: `Asset is expected to have files`,
|
|
67
|
+
});
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
validateAssetFileCount(asset.count, files.length);
|
|
71
|
+
}catch(e){
|
|
72
|
+
errors.push({
|
|
73
|
+
type: "asset",
|
|
74
|
+
id: assetName,
|
|
75
|
+
message: (e as Error).message,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for(const [filePath, { assets }] of filesWithAssets){
|
|
80
|
+
if(assets.length === 0) errors.push({
|
|
81
|
+
type: "file",
|
|
82
|
+
id: filePath,
|
|
83
|
+
message: "File has no matching assets",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return errors;
|
|
87
|
+
}
|
|
88
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import micromatch from "micromatch";
|
|
2
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
3
|
+
type RosterLockEngineConfig = RosterLockV1Config["engine"];
|
|
4
|
+
|
|
5
|
+
import { validatePathVariableValue } from "../../lock/rosters/validate";
|
|
6
|
+
/**
|
|
7
|
+
* Test a single file against piece definition assets
|
|
8
|
+
*/
|
|
9
|
+
export function getMatchingAssetsForFile(
|
|
10
|
+
pieceDefinition: RosterLockEngineConfig['pieceDefinitions'][string],
|
|
11
|
+
pathVariables: Record<string, string>,
|
|
12
|
+
relativePath: string,
|
|
13
|
+
): Array<RosterLockEngineConfig['pieceDefinitions'][string]['assets'][number]> {
|
|
14
|
+
|
|
15
|
+
for(const variableValue of Object.values(pathVariables)){
|
|
16
|
+
validatePathVariableValue(variableValue);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return pieceDefinition.assets.filter((asset) =>(
|
|
20
|
+
asset.glob.some((glob)=>{
|
|
21
|
+
// Replace path variables
|
|
22
|
+
glob = replacePathVariables(glob, pathVariables);
|
|
23
|
+
// check if the relativePath is exactly the glob
|
|
24
|
+
// TODO: eventually we want to see if the glob is a file path and if so, check for exact match
|
|
25
|
+
// Relative path isn't expected to have any glob parts, so an exact match is expected to be ok
|
|
26
|
+
// If a filepath can have glob parts, we may be in trouble
|
|
27
|
+
if(relativePath === glob) return true;
|
|
28
|
+
// check if the relativePath matches the glob
|
|
29
|
+
if(micromatch.isMatch(relativePath, glob)) return true;
|
|
30
|
+
return false;
|
|
31
|
+
})
|
|
32
|
+
));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function replacePathVariables(
|
|
36
|
+
glob: string, pathVariables: Record<string, string>
|
|
37
|
+
){
|
|
38
|
+
for(const [variableName, value] of Object.entries(pathVariables)){
|
|
39
|
+
glob = glob.replaceAll(`<${variableName}>`, value);
|
|
40
|
+
}
|
|
41
|
+
return glob;
|
|
42
|
+
}
|
package/src/match-lock-file/match-config/version-1/usage/files-and-assets/validateAssetFileCount.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EngineAssetDefinition } from "./types";
|
|
2
|
+
|
|
3
|
+
export function validateAssetFileCount(
|
|
4
|
+
validator: EngineAssetDefinition["count"],
|
|
5
|
+
actualCount: number
|
|
6
|
+
){
|
|
7
|
+
if(!Array.isArray(validator)){
|
|
8
|
+
if(validator === "*") return;
|
|
9
|
+
if(actualCount !== validator){
|
|
10
|
+
throw new Error(`Expected ${validator} files, got ${actualCount}`);
|
|
11
|
+
}
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const [min, max] = validator;
|
|
15
|
+
if(actualCount < min){
|
|
16
|
+
throw new Error(`Expected at least ${min} files, got ${actualCount}`);
|
|
17
|
+
}
|
|
18
|
+
if(max === "*") return;
|
|
19
|
+
if(actualCount > max){
|
|
20
|
+
throw new Error(`Expected at most ${max} files, got ${actualCount}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isValidAssetFileCount(
|
|
25
|
+
validator: EngineAssetDefinition["count"],
|
|
26
|
+
actualCount: number
|
|
27
|
+
){
|
|
28
|
+
try {
|
|
29
|
+
validateAssetFileCount(validator, actualCount);
|
|
30
|
+
return true;
|
|
31
|
+
}catch(e){
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { JSON_Unknown } from "@roster-lock/utils";
|
|
2
|
+
|
|
3
|
+
export class SemVer {
|
|
4
|
+
private updateStatus: "none" | "patch" | "minor" | "major" = "none";
|
|
5
|
+
v: {
|
|
6
|
+
major: number,
|
|
7
|
+
minor: number,
|
|
8
|
+
patch: number
|
|
9
|
+
}
|
|
10
|
+
reasons: {
|
|
11
|
+
major: Array<{ reason: string, info: JSON_Unknown }>,
|
|
12
|
+
minor: Array<{ reason: string, info: JSON_Unknown }>,
|
|
13
|
+
patch: Array<{ reason: string, info: JSON_Unknown }>
|
|
14
|
+
} = {
|
|
15
|
+
major: [],
|
|
16
|
+
minor: [],
|
|
17
|
+
patch: [],
|
|
18
|
+
}
|
|
19
|
+
constructor(value: string){
|
|
20
|
+
const parts = value.split(".");
|
|
21
|
+
if(parts.length !== 3) throw new Error("Invalid Semver string");
|
|
22
|
+
this.v = {
|
|
23
|
+
major: SemVer.validateVersion(parts[0], "major"),
|
|
24
|
+
minor: SemVer.validateVersion(parts[1], "minor"),
|
|
25
|
+
patch: SemVer.validateVersion(parts[2], "patch"),
|
|
26
|
+
}
|
|
27
|
+
if(value !== this.toString()){
|
|
28
|
+
throw new Error("Invalid Semver string")
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
addMajor(reason: string, info: JSON_Unknown = {}){
|
|
33
|
+
this.reasons.major.push({ reason, info });
|
|
34
|
+
if(this.updateStatus === "major") return;
|
|
35
|
+
this.updateStatus = "major";
|
|
36
|
+
this.v.major += 1;
|
|
37
|
+
this.v.minor = 0;
|
|
38
|
+
this.v.patch = 0;
|
|
39
|
+
}
|
|
40
|
+
addMinor(reason: string, info: JSON_Unknown = {}){
|
|
41
|
+
this.reasons.minor.push({ reason, info });
|
|
42
|
+
if(this.updateStatus === "minor") return;
|
|
43
|
+
this.updateStatus = "minor";
|
|
44
|
+
this.v.minor += 1;
|
|
45
|
+
this.v.patch = 0;
|
|
46
|
+
}
|
|
47
|
+
addPatch(reason: string, info: JSON_Unknown = {}){
|
|
48
|
+
this.reasons.patch.push({ reason, info });
|
|
49
|
+
if(this.updateStatus === "patch") return;
|
|
50
|
+
this.updateStatus = "patch";
|
|
51
|
+
this.v.patch += 1
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
toString(){
|
|
55
|
+
return [this.v.major, this.v.minor, this.v.patch].join(".")
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
getReasons(){
|
|
59
|
+
return this.reasons;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static validateVersion(value: string, partName: string){
|
|
63
|
+
const v = Number.parseInt(value)
|
|
64
|
+
if(Number.isNaN(v)) throw new Error(`Invalid Semver string: ${partName} version not an integer`)
|
|
65
|
+
return v
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { RosterLockV1Config } from "@roster-lock/types";
|
|
2
|
+
import { diff } from 'json-diff-ts';
|
|
3
|
+
import { SemVer } from "./SemVer";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export function diffLocks(oldLock: RosterLockV1Config, newLock: RosterLockV1Config){
|
|
7
|
+
const versionTracker = new SemVer(oldLock.version);
|
|
8
|
+
|
|
9
|
+
diffRosters(versionTracker, oldLock, newLock);
|
|
10
|
+
|
|
11
|
+
return versionTracker;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function diffRosters(versionTracker: SemVer, oldLock: RosterLockV1Config, newLock: RosterLockV1Config){
|
|
15
|
+
const oldPieceCollections = Object.entries(oldLock.rosters);
|
|
16
|
+
const newPieceCollectionKeys = Object.keys(newLock.rosters);
|
|
17
|
+
|
|
18
|
+
const missingCollections: Array<string> = [];
|
|
19
|
+
const addedCollections = new Set(newPieceCollectionKeys);
|
|
20
|
+
|
|
21
|
+
for(const [key, oldPieces] of oldPieceCollections){
|
|
22
|
+
const newPieces = newLock.rosters[key];
|
|
23
|
+
if(!newPieces){
|
|
24
|
+
versionTracker.addMajor("Missing Piece Collection", { collectionName: key });
|
|
25
|
+
missingCollections.push(key);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
addedCollections.delete(key);
|
|
29
|
+
diffPieces(versionTracker, key, oldPieces, newPieces)
|
|
30
|
+
}
|
|
31
|
+
for(const key of addedCollections){
|
|
32
|
+
versionTracker.addMajor("New Piece Collection", { collectionName: key });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return versionTracker
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
type PieceCollection = RosterLockV1Config["rosters"][string]
|
|
40
|
+
type Piece = PieceCollection[number];
|
|
41
|
+
function diffPieces(versionTracker: SemVer, collection: string, oldLock: PieceCollection, newLock: PieceCollection){
|
|
42
|
+
const newPieces = new Map<string, Piece>()
|
|
43
|
+
for(const newPiece of newLock){
|
|
44
|
+
newPieces.set(newPiece.version.logic, newPiece)
|
|
45
|
+
}
|
|
46
|
+
for(const oldPiece of oldLock){
|
|
47
|
+
const newPiece = newPieces.get(oldPiece.version.logic)
|
|
48
|
+
if(!newPiece){
|
|
49
|
+
versionTracker.addMajor(
|
|
50
|
+
"Removed a Piece", { collection, id: oldPiece.id, logic: oldPiece.version.logic }
|
|
51
|
+
)
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
newPieces.delete(oldPiece.version.logic)
|
|
55
|
+
if(diff(oldPiece, newPiece)){
|
|
56
|
+
versionTracker.addPatch(
|
|
57
|
+
"Updated non gameplay piece info", { collection, id: oldPiece.id, old: oldPiece.downloadSources, new: newPiece.downloadSources }
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
for(const [logic, newPiece] of newPieces){
|
|
62
|
+
versionTracker.addMinor(
|
|
63
|
+
"Added a Piece", { collection, id: newPiece.id, logic }
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
import { RosterLockV1Config, PieceType, SelectedPiece } from "@roster-lock/types";
|
|
3
|
+
|
|
4
|
+
export function ensurePiecesAreInRoster(
|
|
5
|
+
config: RosterLockV1Config,
|
|
6
|
+
pieceType: PieceType,
|
|
7
|
+
selections: Array<SelectedPiece>
|
|
8
|
+
){
|
|
9
|
+
const requireConfig = new Set(config.engine.pieceDefinitions[pieceType].requires);
|
|
10
|
+
if(requireConfig.size !== config.engine.pieceDefinitions[pieceType].requires.length){
|
|
11
|
+
throw new Error(`${pieceType} requires has duplicate items`);
|
|
12
|
+
}
|
|
13
|
+
const roster = config.rosters[pieceType];
|
|
14
|
+
for(const piece of selections){
|
|
15
|
+
const rosterPiece = roster.find(p=>p.id === piece.id);
|
|
16
|
+
if(!rosterPiece){
|
|
17
|
+
throw new Error(`Piece ${piece.id} is not in the roster`);
|
|
18
|
+
}
|
|
19
|
+
const pieceRequiredKeys = Object.keys(piece.required);
|
|
20
|
+
if(pieceRequiredKeys.length !== requireConfig.size){
|
|
21
|
+
throw new Error(`Piece ${piece.id} has incorrect number of required keys`);
|
|
22
|
+
}
|
|
23
|
+
for(const requirePieceType of pieceRequiredKeys){
|
|
24
|
+
if(!requireConfig.has(requirePieceType)){
|
|
25
|
+
throw new Error(`Piece ${piece.id} is missing required piece type ${requirePieceType}`);
|
|
26
|
+
}
|
|
27
|
+
ensureCorrectMandatory(rosterPiece, requirePieceType, piece.required[requirePieceType].mandatory);
|
|
28
|
+
ensurePiecesAreInRoster(config, requirePieceType, piece.required[requirePieceType].mandatory);
|
|
29
|
+
ensureSelectionIsAllowed(rosterPiece, requirePieceType, piece.required[requirePieceType].selectable);
|
|
30
|
+
ensurePiecesAreInRoster(config, requirePieceType, piece.required[requirePieceType].selectable);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
type RosterPiece = RosterLockV1Config["rosters"][string][number];
|
|
36
|
+
function ensureCorrectMandatory(
|
|
37
|
+
rosterPiece: RosterPiece, requiredPieceType: string, mandatoryPieces: Array<SelectedPiece>
|
|
38
|
+
){
|
|
39
|
+
const rosterMandatory = rosterPiece.requiredPieces[requiredPieceType];
|
|
40
|
+
if(!rosterMandatory) throw new Error(`Roster Piece ${rosterPiece.id} missing required ${requiredPieceType}`);
|
|
41
|
+
if(rosterMandatory.expected.length !== mandatoryPieces.length){
|
|
42
|
+
throw new Error(`Piece ${rosterPiece.id} has incorrect number of required pieces for ${requiredPieceType}`);
|
|
43
|
+
}
|
|
44
|
+
for(let i = 0; i < rosterMandatory.expected.length; i++){
|
|
45
|
+
const mandatoryId = rosterMandatory.expected[i];
|
|
46
|
+
const mandatoryPiece = mandatoryPieces[i];
|
|
47
|
+
if(mandatoryId !== mandatoryPiece.id){
|
|
48
|
+
throw new Error(`Piece ${rosterPiece.id} has incorrect required piece of ${requiredPieceType} at ${i}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ensureSelectionIsAllowed(
|
|
54
|
+
rosterPiece: RosterPiece, requiredPieceType: string, selectedPieces: Array<SelectedPiece>
|
|
55
|
+
){
|
|
56
|
+
const rosterMandatory = rosterPiece.requiredPieces[requiredPieceType];
|
|
57
|
+
if(!rosterMandatory) throw new Error(`Roster Piece ${rosterPiece.id} missing required ${requiredPieceType}`);
|
|
58
|
+
if(!rosterMandatory.selectable && selectedPieces.length > 0){
|
|
59
|
+
throw new Error(`Piece ${rosterPiece.id} does not allow custom selection for ${requiredPieceType}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
|
|
2
|
+
import { RunUntrustedError } from "./constants";
|
|
3
|
+
|
|
4
|
+
export async function handleValidationResult(
|
|
5
|
+
script: { src: string }, result: Promise<unknown>
|
|
6
|
+
){
|
|
7
|
+
const isValid = await (async ()=>{
|
|
8
|
+
try {
|
|
9
|
+
return await result;
|
|
10
|
+
}catch(e){
|
|
11
|
+
throw new RunUntrustedError(
|
|
12
|
+
script.src, e instanceof Error ? e.message : String(e), e
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
})();
|
|
16
|
+
const errorStatus = normalizeError(isValid);
|
|
17
|
+
if(!errorStatus.passed){
|
|
18
|
+
throw new RunUntrustedError(
|
|
19
|
+
script.src, errorStatus.message, isValid
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const INVALID_VALUE = "Invalid return type for validation";
|
|
25
|
+
const FAILED_WITHOUT_MESSAGE = "Validation Failed";
|
|
26
|
+
function normalizeError(validResult: unknown): (
|
|
27
|
+
| { passed: true }
|
|
28
|
+
| { passed: false, message: string }
|
|
29
|
+
){
|
|
30
|
+
if(typeof validResult === "boolean"){
|
|
31
|
+
if(validResult) return { passed: true };
|
|
32
|
+
return { passed: false, message: FAILED_WITHOUT_MESSAGE };
|
|
33
|
+
}
|
|
34
|
+
if(Array.isArray(validResult)){
|
|
35
|
+
const [passed, reason] = validResult;
|
|
36
|
+
if(typeof passed !== "boolean"){
|
|
37
|
+
return { passed: false, message: INVALID_VALUE };
|
|
38
|
+
}
|
|
39
|
+
if(passed) return { passed: true };
|
|
40
|
+
return {
|
|
41
|
+
passed: false,
|
|
42
|
+
message: typeof reason === "string" ? reason : FAILED_WITHOUT_MESSAGE,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
if(typeof validResult === "string"){
|
|
46
|
+
return {
|
|
47
|
+
passed: false,
|
|
48
|
+
message: validResult
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if(validResult === null || validResult === void 0) return { passed: true };
|
|
52
|
+
return { passed: false, message: INVALID_VALUE };
|
|
53
|
+
}
|
|
54
|
+
|