├── .gitignore ├── CHANGELOG.MD ├── LICENSE ├── README.md ├── cli.js ├── lib ├── directory.js ├── files.js ├── guid.js ├── index.js ├── manifest.js ├── metadata.js ├── schema.js ├── schemas │ ├── config.js │ ├── definitionFiles │ │ ├── scorm12edition │ │ │ ├── adlcp_rootv1p2.xsd │ │ │ ├── ims_xml.xsd │ │ │ ├── imscp_rootv1p1p2.xsd │ │ │ └── imsmd_rootv1p2p1.xsd │ │ ├── scorm20043rdedition │ │ │ ├── XMLSchema.dtd │ │ │ ├── adlcp_v1p3.xsd │ │ │ ├── adlnav_v1p3.xsd │ │ │ ├── adlseq_v1p3.xsd │ │ │ ├── datatypes.dtd │ │ │ ├── imscp_v1p1.xsd │ │ │ ├── imsss_v1p0.xsd │ │ │ ├── imsss_v1p0auxresource.xsd │ │ │ ├── imsss_v1p0control.xsd │ │ │ ├── imsss_v1p0delivery.xsd │ │ │ ├── imsss_v1p0limit.xsd │ │ │ ├── imsss_v1p0objective.xsd │ │ │ ├── imsss_v1p0random.xsd │ │ │ ├── imsss_v1p0rollup.xsd │ │ │ ├── imsss_v1p0seqrule.xsd │ │ │ ├── imsss_v1p0util.xsd │ │ │ └── xml.xsd │ │ └── scorm20044thedition │ │ │ ├── XMLSchema.dtd │ │ │ ├── adlcp_v1p3.xsd │ │ │ ├── adlnav_v1p3.xsd │ │ │ ├── adlseq_v1p3.xsd │ │ │ ├── datatypes.dtd │ │ │ ├── imscp_v1p1.xsd │ │ │ ├── imsss_v1p0.xsd │ │ │ ├── imsss_v1p0auxresource.xsd │ │ │ ├── imsss_v1p0control.xsd │ │ │ ├── imsss_v1p0delivery.xsd │ │ │ ├── imsss_v1p0limit.xsd │ │ │ ├── imsss_v1p0objective.xsd │ │ │ ├── imsss_v1p0random.xsd │ │ │ ├── imsss_v1p0rollup.xsd │ │ │ ├── imsss_v1p0seqrule.xsd │ │ │ ├── imsss_v1p0util.xsd │ │ │ └── xml.xsd │ ├── metadata.js │ ├── scorm12.js │ └── scorm2004.js └── utils.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | node_modules 3 | test -------------------------------------------------------------------------------- /CHANGELOG.MD: -------------------------------------------------------------------------------- 1 | # scopackager changelog 2 | 3 | ## 0.2.7 4 | * fix config identifier not being used when generating the schema manifests 5 | 6 | ## 0.2.6 7 | * included MIT LICENSE 8 | * fix for non-latin languages 9 | 10 | ## 0.2.5 11 | * changed behavior of adding timestamp to .zip file: by default, this is *not* added. It can be added by setting `package.appendTimeToOutput: true` in the options object. 12 | 13 | ## 0.2.4 14 | 15 | * package.vcard.org value is now correctly assigned 16 | * language defaults changed to 'en' and any default string values (metadata descriptions) changed to english 17 | * modify README.md options formatting to show all default values 18 | * add timestamp to .zip file outputs so repeated packaging doesn't overwrite existing archives 19 | * fixed typo in metadata.js (appearence -> appearance) 20 | 21 | ## 0.2.3 22 | 23 | * fixed mastery score to 0 24 | 25 | ## 0.2.2 26 | 27 | * fixed package.json 28 | 29 | ## 0.2.1 30 | 31 | * renamed CHANGELOG.MD to CHANGELOG.md 32 | 33 | ## 0.2.0 34 | 35 | * CLI implementation init 36 | * replaced archiver.bulk (deprecated) in favor of archiver.directory 37 | 38 | ## 0.1.7 39 | 40 | * Basic functionality present, mostly spec-compliant 41 | 42 | ## 0.1.3 43 | 44 | * First release capable of doing anything useful 45 | * Still lots of basic functionality missing 46 | 47 | ## 0.1.0 48 | 49 | * Initial experiment -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2022 lmihaidaniel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | `version 0.2.7` 2 | 3 | ## Documentation 4 | 5 | Creates SCORM package from source directory. 6 | 7 | * Supported Scorm versions: 8 | * SCORM 1.2 9 | * SCORM 2004 3rd Edition 10 | * SCORM 2004 4th Edition 11 | 12 | ## Installation 13 | 14 | ```bash 15 | npm install simple-scorm-packager 16 | ``` 17 | 18 | ## Initialization Options Object 19 | {type} [default] 20 | 21 | * `version` {string} ['1.2'] Version of SCORM schema. Available options: 22 | * '1.2' 23 | * '2004 3rd Edition' alias '2004.3' alias '2004v3' 24 | * '2004 4th Edition' alias '2004.4' alias '2004v4' 25 | * `organization` {string} [''] Company name 26 | * `language` {string} ['en'] Language of the package ( ISO ) 27 | * `title` {string} [''] 28 | * `identifier` {string} [null] If empty, identifier is generated using: 29 | \`${package.author || 'com'}.${organization || 'company'}.${title || ''}.${generated uuid}\` 30 | * `masteryScore` {number} [80] 31 | * `startingPage` {string} ['index.html'] 32 | * `source` {string} ['./'] The path to files from which the package will be created 33 | * `package` {object} Available options: 34 | * `zip` {boolean} [false] Archives package (`NAME_VERSION_DATE.zip`) 35 | * `appendTimeToOutput` {boolean} [false] Add full Unix time milliseconds to the zip file output, so repeated builds are unique (`NAME_VERSION_DATE_TIMESTAMP.zip`) 36 | * `outputFolder` {string} ['./scorm'] The folder path where you want the zip file 37 | * `size` {number} [null] Provide the package size in bytes, automatically calculated when not set, 38 | * `name` {string} [\`{$title}\`] Package name, defaults to scorm title 39 | * `author` {string} [''] Author name, used as default for vcard if not provided 40 | * `version` {string} [process.env.npm_package_version || '1.0.0'] Package version 41 | * `organization` {string} [\`${organization}\`] Company name 42 | * `date` {string} [current date YYYY-MM-DD] Package date 43 | * `vcard` {object} : 44 | * `author` {string} [\`${package.author}\`] Author name 45 | * `org` {string} [\`${package.organization}\` || \`${organization}\`] Organization name, defaults to `organization` 46 | * `tel` {string} [''] Telephone number(s) 47 | * `address` {string} [''] Address 48 | * `mail` {string} [''] E-mail contact 49 | * `url` {string} [''] website url 50 | * `description` {string} [''] Provide the course description or the Project Information 51 | * `keywords` {array} [[]] Keywords 52 | * `duration` {string} ['PT0H0M0S'] The time the media takes to play through, format PT#H#M#S 53 | * `typicalDuration` {string} [\`${package.duration}\` || 'PT0H0M0S'] The time it will take for a typical learner to fully experience the program, format PT#H#M#S 54 | * `requirements` {array of objects of the following structure} [[]] 55 | * `type` {string} The type of requirement, eg.: Browser, Os 56 | * `name` {string} The name of the type of requirement, eg.: Microsoft Internet Explorer 57 | * `version` {string} The minimum version of the requirement 58 | * `rights` {string} [\`© ${organization || ''}. All rights reserved.\`] Copyright information 59 | 60 | 61 | ## Programatic usage 62 | 63 | ```javascript 64 | var scopackager = require('simple-scorm-packager'); 65 | 66 | scopackager({ 67 | version: '2004 4th Edition', 68 | organization: 'Test Company', 69 | title: 'Test Course', 70 | language: 'fr-FR', 71 | identifier: '00', 72 | masteryScore: 80, 73 | startingPage: 'index.html', 74 | source: './myProjectFolder', 75 | package: { 76 | version: "0.0.1", 77 | zip: true, 78 | outputFolder: './scormPackages' 79 | } 80 | }, function(msg){ 81 | console.log(msg); 82 | }); 83 | ``` 84 | 85 | ## Adding it to npm scripts 86 | If you are packaging a project which utilizes npm and has a package.json file, follow the instructions below for adding a SCORM packager to your npm scripts. 87 | 1. Create a JavaScript file (typically at the root of your project in the same directory as package.json) `scoPackager.js` 88 | 2. The file should contain code to execute this package. Example: 89 | ```javascript 90 | var scopackager = require('simple-scorm-packager'); 91 | var path = require('path'); 92 | 93 | const config = { 94 | version: '1.2', 95 | organization: 'My Amazing Company', 96 | title: 'Test Course', 97 | language: 'en-US', 98 | masteryScore: 80, 99 | startingPage: 'index.html', 100 | source: path.join(__dirname, 'build'), 101 | package: { 102 | version: process.env.npm_package_version, 103 | zip: true, 104 | author: 'Firstname Lastname', 105 | outputFolder: path.join(__dirname, 'scorm_packages'), 106 | description: 'A test of the course packaging module', 107 | keywords: ['scorm', 'test', 'course'], 108 | typicalDuration: 'PT0H5M0S', 109 | rights: `©${new Date().getFullYear()} My Amazing Company. All right reserved.`, 110 | vcard: { 111 | author: 'Firstname Lastname', 112 | org: 'My Amazing Company', 113 | tel: '(000) 000-0000', 114 | address: 'my address', 115 | mail: 'my@email.com', 116 | url: 'https://mydomain.com' 117 | } 118 | } 119 | }; 120 | 121 | scopackager(config, function(msg){ 122 | console.log(msg); 123 | process.exit(0); 124 | }); 125 | ``` 126 | 3. In the scripts portion of your package.json, add the following: `"package-scorm": "node scoPackager.js"` (replace the .js file name with the name (and path) of the file containing your script from step 2) 127 | 4. You can now package your project for SCORM by running `npm run package-scorm` from the command line. 128 | 129 | ## USE IT AS CLI 130 | if installed globally you can use it directly in command line 131 | 132 | ```bash 133 | $ simple-scorm-packager 134 | or 135 | $ scopackager 136 | ``` -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | var path = require("path"), 3 | fs = require("fs"), 4 | inquirer = require("inquirer"), 5 | utils = require(path.join(__dirname, "lib"+path.sep+"utils.js")), 6 | scopackage = require(path.join(__dirname, "lib"+path.sep+"index.js")), 7 | generateDefaultSettings = require(path.join(__dirname,"lib"+path.sep+"schemas"+path.sep+"config.js")); 8 | 9 | inquirer.registerPrompt("directory", require("inquirer-directory")); 10 | 11 | function getPackageName () { 12 | try { 13 | const pkg = require(path.join(process.cwd(), "package.json")) 14 | return pkg.name 15 | } catch (e) { 16 | return "" 17 | } 18 | } 19 | 20 | var validators = { 21 | notEmpty: function(value){ 22 | if(value&&utils.cleanAndTrim(value)!="") return true; 23 | return "Please enter a valid information"; 24 | }, 25 | number: function(value) { 26 | return !isNaN(parseFloat(value)) || "Please enter a number"; 27 | } 28 | }; 29 | 30 | var settings = { 31 | source: process.cwd(), 32 | uuid: utils.uuid(), 33 | version: "1.2", 34 | language: "en", 35 | organization: "", 36 | title: getPackageName(), 37 | identifier: "", 38 | masteryScore: 80, 39 | startingPage: "index.html", 40 | package: { 41 | zip: true 42 | } 43 | }; 44 | 45 | var cli_init = function(next){ 46 | inquirer 47 | .prompt([{ 48 | type: "list", 49 | name: "version", 50 | message: "Select scorm version:", 51 | choices: [ 52 | "1.2", 53 | new inquirer.Separator(), 54 | { 55 | name: "2004 1st Edition", 56 | disabled: "Unavailable at this time" 57 | }, 58 | { 59 | name: "2004 2nd Edition", 60 | disabled: "Unavailable at this time" 61 | }, 62 | "2004 3rd Edition", 63 | "2004 4th Edition" 64 | ]},{ 65 | type: "input", 66 | name: "title", 67 | message: "Select title:", 68 | default: settings.title, 69 | validate: validators.notEmpty, 70 | filter: function(value) { 71 | return value.trim(); 72 | } 73 | },{ 74 | type: "input", 75 | name: "organization", 76 | message: "Select organization:", 77 | validate: validators.notEmpty, 78 | filter: function(value) { 79 | return value.trim(); 80 | } 81 | }, 82 | { 83 | type: "input", 84 | name: "language", 85 | message: "Select language:", 86 | default: settings.language, 87 | validate: validators.notEmpty, 88 | filter: function(value) { 89 | return value.trim().toLowerCase(); 90 | } 91 | }, 92 | { 93 | type: "input", 94 | name: "masteryScore", 95 | message: "Select mastery score [Range 0-100]:", 96 | default: settings.masteryScore, 97 | filter: Number, 98 | validate: validators.number 99 | }, 100 | { 101 | type: "input", 102 | name: "startingPage", 103 | message: "Select starting page:", 104 | default: settings.startingPage, 105 | validate: validators.notEmpty, 106 | filter: function(value) { 107 | return value.trim(); 108 | } 109 | } 110 | ]).then(function(answers) { 111 | settings.version = answers.version; 112 | settings.title = answers.title; 113 | settings.organization = answers.organization; 114 | settings.language = answers.language; 115 | settings.masteryScore = answers.masteryScore; 116 | settings.startingPage = answers.startingPage; 117 | next(); 118 | }); 119 | } 120 | 121 | var cli_identifier = function(next){ 122 | inquirer 123 | .prompt([ 124 | { 125 | type: "input", 126 | name: "identifier", 127 | message: "Select an identifier:", 128 | default: (utils.acronym(settings.organization)+"00").toUpperCase(), 129 | validate: validators.notEmpty, 130 | filter: function(value) { 131 | return value.trim(); 132 | } 133 | },{ 134 | type: "input", 135 | name: "uuid", 136 | message: "Select an unique identifier:", 137 | default: settings.uuid, 138 | validate: validators.notEmpty, 139 | filter: function(value) { 140 | return value.trim(); 141 | } 142 | } 143 | ]) 144 | .then(function(answers) { 145 | settings.identifier = answers.identifier; 146 | settings.uuid = answers.uuid; 147 | next(); 148 | }); 149 | } 150 | 151 | var cli_source = function(next){ 152 | inquirer 153 | .prompt([ 154 | { 155 | type: "directory", 156 | name: "from", 157 | message: "Select source directory:", 158 | basePath: settings.source 159 | } 160 | ]) 161 | .then(function(answers) { 162 | var dir = (answers.from || settings.source) + path.sep; 163 | settings.source = path.resolve(dir); 164 | next(); 165 | }); 166 | } 167 | 168 | cli_init(function(){ 169 | cli_identifier(function(){ 170 | cli_source(function(){ 171 | var config = generateDefaultSettings(settings); 172 | /*TODO 173 | - add cli input for package 174 | - add cli helper 175 | - add cli input config file 176 | */ 177 | scopackage(config); 178 | }); 179 | }) 180 | }); -------------------------------------------------------------------------------- /lib/directory.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var fs = require("fs"); 4 | var path = require("path"); 5 | var async = require("async"); 6 | 7 | function readSizeRecursive(item, ignoreRegEx, callback) { 8 | var cb; 9 | var ignoreRegExp; 10 | 11 | if (!callback) { 12 | cb = ignoreRegEx; 13 | ignoreRegExp = null; 14 | } else { 15 | cb = callback; 16 | ignoreRegExp = ignoreRegEx; 17 | } 18 | 19 | fs.lstat(item, function lstat(e, stats) { 20 | var total = !e ? stats.size || 0 : 0; 21 | 22 | if (!e && stats.isDirectory()) { 23 | fs.readdir(item, function readdir(err, list) { 24 | if (err) { 25 | return cb(err); 26 | } 27 | 28 | async.forEach( 29 | list, 30 | function iterate(dirItem, next) { 31 | readSizeRecursive( 32 | path.join(item, dirItem), 33 | ignoreRegExp, 34 | function readSize(error, size) { 35 | if (!error) { 36 | total += size; 37 | } 38 | 39 | next(error); 40 | } 41 | ); 42 | }, 43 | function done(finalErr) { 44 | cb(finalErr, total); 45 | } 46 | ); 47 | }); 48 | } else { 49 | if (ignoreRegExp && ignoreRegExp.test(item)) { 50 | total = 0; 51 | } 52 | 53 | cb(e, total); 54 | } 55 | }); 56 | } 57 | 58 | module.exports = readSizeRecursive; 59 | -------------------------------------------------------------------------------- /lib/files.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"), path = require("path"), url = require("url"); 2 | 3 | var _walk = function(dir, excludeSchemaFiles, callback) { 4 | var fileList = fs.readdirSync(dir), finalFileList = []; 5 | 6 | fileList.forEach(function(file) { 7 | var isDirectory = fs.statSync(path.join(dir, file)).isDirectory(); 8 | if (isDirectory) { 9 | var newDir = path.join(dir, file); 10 | _walk(newDir, excludeSchemaFiles, function(results) { 11 | finalFileList = finalFileList.concat(results); 12 | }); 13 | } else { 14 | var newFile = path.join(dir, file); 15 | var ext = path.extname(file); 16 | if (!excludeSchemaFiles) { 17 | finalFileList.push(newFile); 18 | } else { 19 | if ( 20 | ext !== ".xsd" && 21 | ext !== ".dtd" && 22 | file !== "metadata.xml" && 23 | file !== "imsmanifest.xml" 24 | ) { 25 | finalFileList.push(newFile); 26 | } 27 | } 28 | } 29 | }); 30 | 31 | return callback(finalFileList); 32 | }; 33 | 34 | var files = function(dir, excludeSchemaFiles) { 35 | var fileList = []; 36 | 37 | dir = path.normalize(dir); 38 | 39 | _walk(dir, excludeSchemaFiles, function(results) { 40 | results.forEach(function(value) { 41 | value = value.split(dir + path.sep)[1] || value; 42 | fileList.push(url.format(value)); 43 | }); 44 | }); 45 | 46 | return fileList; 47 | }; 48 | 49 | module.exports = files; 50 | -------------------------------------------------------------------------------- /lib/guid.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var utils = require("./utils"); 3 | 4 | module.exports = function(obj) { 5 | var com = utils.acronym(obj.package.author || "c o m"); 6 | var company = utils.cleanAndTrim(obj.package.organization || "company"); 7 | var project = utils.cleanAndTrim(obj.title, ""); 8 | return com + "." + company + "." + project + "." + obj.uuid; 9 | }; 10 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"), 2 | fse = require("fs-extra"), 3 | path = require("path"), 4 | getDirectorySize = require("./directory.js"), 5 | files = require("./files.js"), 6 | config = require("./schemas/config"), 7 | schema = require("./schema.js"), 8 | metadata = require("./metadata.js"), 9 | manifest = require("./manifest.js"), 10 | utils = require("./utils"); 11 | 12 | var _logSuccess = function(msg) { 13 | var date = new Date(); 14 | var time = date.getHours() + 15 | ":" + 16 | date.getMinutes() + 17 | ":" + 18 | date.getSeconds(); 19 | console.log( 20 | "[" + time + "]", 21 | "SCORM", 22 | "'" + "\x1b[32m" + msg + "\x1b[0m" + "'" 23 | ); 24 | }; 25 | 26 | var _logError = function(err) { 27 | var date = new Date(); 28 | var time = date.getHours() + 29 | ":" + 30 | date.getMinutes() + 31 | ":" + 32 | date.getSeconds(); 33 | console.log("[" + time + "]" + "\x1b[31m", err, "\x1b[0m"); 34 | }; 35 | 36 | var buildPackage = function(obj, callback) { 37 | _logSuccess("Init"); 38 | callback = callback || _logSuccess; 39 | obj = config(obj); 40 | var schemaVersion, schemaDefinition; 41 | 42 | switch (obj.version) { 43 | case "1.2": 44 | schemaVersion = "scorm12"; 45 | schemaDefinition = "scorm12edition"; 46 | break; 47 | case "2004.3": 48 | case "2004v3": 49 | case "2004 3rd Edition": 50 | schemaVersion = "scorm2004"; 51 | schemaDefinition = "scorm20043rdedition"; 52 | break; 53 | case "2004.4": 54 | case "2004v4": 55 | case "2004 4th Edition": 56 | schemaVersion = "scorm2004"; 57 | schemaDefinition = "scorm20044thedition"; 58 | break; 59 | } 60 | 61 | if (!schemaVersion) { 62 | _logError("Supported versions:\n1.2\n2004 3rd Edition\n2004 4th Edition"); 63 | return; 64 | } 65 | 66 | if (obj.package.size === "") { 67 | getDirectorySize(path.resolve(obj.source), null, function(err, bytes) { 68 | if (err) { 69 | throw err; 70 | } 71 | obj.package.size = bytes; 72 | }); 73 | } 74 | 75 | var rootDir = path.dirname(fs.realpathSync(__filename)), 76 | definitionFileList = files( 77 | path.join(rootDir, "schemas", "definitionFiles", schemaDefinition) 78 | ).map(function(file) { 79 | return { 80 | name: file, 81 | source: path.join( 82 | rootDir, 83 | "schemas", 84 | "definitionFiles", 85 | schemaDefinition, 86 | file 87 | ), 88 | destination: path.join(obj.source, file) 89 | }; 90 | }); 91 | 92 | fse.outputFile( 93 | path.join(obj.source, "imsmanifest.xml"), 94 | manifest(schemaVersion, obj), 95 | function(err) { 96 | if (err) { 97 | return _logError(err); 98 | } else { 99 | _logSuccess("create " + path.join(obj.source, "imsmanifest.xml")); 100 | fse.outputFile( 101 | path.join(obj.source, "metadata.xml"), 102 | metadata(obj), 103 | function(err) { 104 | if (err) { 105 | return _logError(err); 106 | } else { 107 | _logSuccess("create " + path.join(obj.source, "metadata.xml")); 108 | definitionFileList.forEach(function(file) { 109 | try { 110 | fse.copySync(file.source, file.destination); 111 | _logSuccess("create " + file.destination); 112 | } catch (err) { 113 | _logError(err); 114 | } 115 | }); 116 | if (obj.package.zip) { 117 | var archiver = require("archiver"); 118 | var utcTime = new Date().getTime(); 119 | fse.ensureDirSync(obj.package.outputFolder); 120 | let finalFilename = `${utils.cleanAndTrim(obj.package.name)}_v${obj.package.version}_${obj.package.date}${obj.package.appendTimeToOutput ? `_${utcTime}` : ''}.zip`; 121 | var zipOutput = path.join( 122 | obj.package.outputFolder, 123 | finalFilename 124 | ); 125 | _logSuccess("Archiving " + obj.source + " to " + zipOutput); 126 | var output = fs.createWriteStream(zipOutput); 127 | var archive = archiver("zip"); 128 | output.on("close", function() { 129 | _logSuccess( 130 | finalFilename + " " + archive.pointer() + " total bytes" 131 | ); 132 | callback("Done"); 133 | }); 134 | archive.on("error", function(err) { 135 | _logError(err); 136 | throw err; 137 | }); 138 | archive.pipe(output); 139 | archive.directory(obj.source, ""); 140 | 141 | //archive.bulk([{ 142 | //expand: true, 143 | //cwd: obj.source, 144 | //src: ['**/*'], 145 | //dest: "" 146 | //}]); 147 | 148 | archive.finalize(); 149 | } else { 150 | callback("Done"); 151 | } 152 | } 153 | } 154 | ); 155 | } 156 | } 157 | ); 158 | }; 159 | 160 | module.exports = buildPackage; 161 | -------------------------------------------------------------------------------- /lib/manifest.js: -------------------------------------------------------------------------------- 1 | var os = require("os"), 2 | builder = require("xmlbuilder"), 3 | path = require("path"), 4 | schema = require("./schema.js"), 5 | files = require("./files.js"); 6 | 7 | var manifest = function(version, obj) { 8 | var configObj = schema.config(obj), 9 | lisOfFiles = files(path.normalize(obj.source), "excludeManifestFiles"); 10 | 11 | configObj.files = lisOfFiles.map(function(value) { 12 | var rObj = {}; 13 | rObj["@href"] = value; 14 | return rObj; 15 | }); 16 | 17 | return builder 18 | .create("manifest", { 19 | version: "1.0", 20 | encoding: "utf-8", 21 | standalone: false 22 | }) 23 | .ele(schema[version](configObj)) 24 | .end({ 25 | pretty: true, 26 | newline: os.EOL 27 | }); 28 | }; 29 | 30 | module.exports = manifest; 31 | -------------------------------------------------------------------------------- /lib/metadata.js: -------------------------------------------------------------------------------- 1 | var os = require("os"), 2 | builder = require("xmlbuilder"), 3 | path = require("path"), 4 | schema = require("./schema.js"), 5 | files = require("./files.js"); 6 | 7 | var metadata = function(obj) { 8 | var configObj = schema.config(obj); 9 | 10 | return builder 11 | .create("lom", { 12 | version: "1.0", 13 | encoding: "utf-8" 14 | }) 15 | .ele(schema["metadata"](configObj)) 16 | .end({ 17 | pretty: true, 18 | newline: os.EOL 19 | }); 20 | }; 21 | 22 | module.exports = metadata; 23 | -------------------------------------------------------------------------------- /lib/schema.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | config: require("./schemas/config"), 3 | metadata: require("./schemas/metadata.js"), 4 | scorm12: require("./schemas/scorm12.js"), 5 | scorm2004: require("./schemas/scorm2004.js") 6 | }; 7 | -------------------------------------------------------------------------------- /lib/schemas/config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | var now = new Date(); 4 | var timestamp = now.getTime(); 5 | 6 | var nowDate = function() { 7 | now.setDate(now.getDate()); 8 | return now.getFullYear() + '-' + ('0' + (now.getMonth() + 1)).slice(-2) + '-' + ('0' + now.getDate()).slice(-2); 9 | } 10 | 11 | var stringToArray = function(value){ 12 | if(value instanceof Array){ 13 | return value; 14 | }else if(typeof value === "string"){ 15 | var arr = []; 16 | if(value) arr.push(value); 17 | return arr; 18 | }else{ 19 | var arrOfVals = []; 20 | for( var k in value ) { 21 | if(value[k]) arrOfVals.push( value[k] ); 22 | } 23 | return arrOfVals; 24 | } 25 | } 26 | 27 | var uuid = function() { 28 | var d = timestamp; 29 | var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 30 | var r = (d + Math.random()*16)%16 | 0; 31 | d = Math.floor(d/16); 32 | return (c=='x' ? r : (r&0x3|0x8)).toString(16); 33 | }); 34 | return uuid; 35 | }; 36 | 37 | module.exports = function(obj) { 38 | if (!obj.package) obj.package = {}; 39 | if (!obj.package.vcard) obj.package.vcard = {}; 40 | return { 41 | uuid: obj.uuid || uuid(), 42 | version: obj.version || '1.2', 43 | language: obj.language || 'en', 44 | organization: obj.organization || '', 45 | title: obj.title || '', 46 | identifier: obj.identifier, 47 | masteryScore: obj.masteryScore != null ? obj.masteryScore : 80, 48 | startingPage: obj.startingPage || 'index.html', 49 | package: { 50 | name: obj.package.name || obj.title || '', 51 | author: obj.package.author || '', 52 | description: obj.package.description || obj.description || '', 53 | organization: obj.package.organization || obj.organization || '', 54 | date: obj.package.date || nowDate(), 55 | timestamp: timestamp, 56 | size: obj.package.size || '', 57 | version: obj.package.version || process.env.npm_package_version || '1.0.0', 58 | outputFolder: obj.package.outputFolder || './scorm', 59 | duration : obj.package.duration || 'PT0H0M0S', 60 | typicalDuration: obj.package.typicalDuration || obj.package.duration || 'PT0H0M0S', 61 | educational: obj.package.educational || obj.package.description || obj.description || '', 62 | rights: obj.package.rights || `© ${obj.organization || ''}. All rights reserved.`, 63 | requirements: obj.package.requirements || [], 64 | keywords: stringToArray(obj.package.keywords || ''), 65 | status: obj.package.status || 'final', 66 | vcard: { 67 | version: obj.package.vcard.version || obj.package.version || process.env.npm_package_version || '1.0.0', 68 | author: obj.package.vcard.author || obj.package.author || '', 69 | org: obj.package.vcard.org || obj.package.organization || obj.organization || '', 70 | tel: stringToArray(obj.package.vcard.tel || ''), 71 | address: stringToArray(obj.package.vcard.address || ''), 72 | mail: stringToArray(obj.package.vcard.mail || ''), 73 | url: obj.package.vcard.url || '' 74 | }, 75 | zip: obj.package.zip, 76 | appendTimeToOutput: typeof obj.package.appendTimeToOutput === 'boolean' ? obj.package.appendTimeToOutput : false 77 | }, 78 | source: obj.source ? path.normalize(obj.source) : path.normalize('./') 79 | }; 80 | }; -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm12edition/adlcp_rootv1p2.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm12edition/ims_xml.xsd: -------------------------------------------------------------------------------- 1 | In namespace-aware XML processors, the "xml" prefix is bound to the namespace name http://www.w3.org/XML/1998/namespace. Do not reference this file in XML instances Schawn Thropp: Changed the uriReference type to string type Refers to universal XML 1.0 lang attribute Refers to XML Base: http://www.w3.org/TR/xmlbase 2 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm12edition/imscp_rootv1p1p2.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | DRAFT XSD for IMS Content Packaging version 1.1 DRAFT 20 | Copyright (c) 2001 IMS GLC, Inc. 21 | 2000-04-21, Adjustments by T.D. Wason from CP 1.0. 22 | 2001-02-22, T.D.Wason: Modify for 2000-10-24 XML-Schema version. Modified to support extension. 23 | 2001-03-12, T.D.Wason: Change filename, target and meta-data namespaces and meta-data fielname. Add meta-data to itemType, fileType and organizationType. 24 | Do not define namespaces for xml in XML instances generated from this xsd. 25 | Imports IMS meta-data xsd, lower case element names. 26 | This XSD provides a reference to the IMS meta-data root element as imsmd:record 27 | If the IMS meta-data is to be used in the XML instance then the instance must define an IMS meta-data prefix with a namespace. The meta-data targetNamespace should be used. 28 | 2001-03-20, Thor Anderson: Remove manifestref, change resourceref back to identifierref, change manifest back to contained by manifest. --Tom Wason: manifest may contain _none_ or more manifests. 29 | 2001-04-13 Tom Wason: corrected attirbute name structure. Was misnamed type. 30 | 2001-05-14 Schawn Thropp: Made all complexType extensible with the group.any 31 | Added the anyAttribute to all complexTypes. Changed the href attribute on the fileType and resourceType to xsd:string 32 | Changed the maxLength of the href, identifierref, parameters, structure attributes to match the Information model. 33 | 2001-07-25 Schawn Thropp: Changed the namespace for the Schema of Schemas to the 5/2/2001 W3C XML Schema 34 | Recommendation. attributeGroup attr.imsmd deleted, was not used anywhere. Any attribute declarations that have 35 | use = "default" changed to use="optional" - attr.structure.req. 36 | Any attribute declarations that have value="somevalue" changed to default="somevalue", 37 | attr.structure.req (hierarchical). Removed references to IMS MD Version 1.1. 38 | Modified attribute group "attr.resourcetype.req" to change use from optional 39 | to required to match the information model. As a result the default value also needed to be removed 40 | Name change for XSD. Changed to match version of CP Spec 41 | 42 | 43 | 44 | Inclusions and Imports 45 | 46 | 47 | 48 | 49 | 50 | Attribute Declarations 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | element groups 158 | 159 | 160 | 161 | 162 | Any namespaced element from any namespace may be included within an "any" element. The namespace for the imported element must be defined in the instance, and the schema must be imported. 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/XMLSchema.dtd: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 18 | 19 | 20 | 23 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | %xs-datatypes; 108 | 109 | 111 | 117 | 129 | 132 | 133 | 134 | 138 | 139 | 141 | 142 | 143 | 146 | 147 | 155 | 156 | 157 | 159 | 160 | 162 | 163 | 164 | 168 | 169 | 171 | 172 | 173 | 176 | 177 | 179 | 180 | 181 | 185 | 186 | 189 | 190 | 192 | 193 | 194 | 210 | 212 | 214 | 215 | 216 | 217 | 224 | 225 | 226 | 231 | 232 | 233 | 238 | 239 | 240 | 245 | 246 | 248 | 249 | 252 | 253 | 254 | 255 | 256 | 263 | 264 | 277 | 278 | 279 | 284 | 285 | 286 | 287 | 288 | 289 | 299 | 301 | 302 | 303 | 304 | 305 | 307 | 310 | 315 | 316 | 317 | 318 | 319 | 320 | 324 | 325 | 326 | 330 | 331 | 332 | 337 | 338 | 339 | 343 | 344 | 348 | 349 | 350 | 351 | 355 | 356 | 357 | 362 | 363 | 365 | 369 | 370 | 371 | 377 | 378 | 379 | 381 | 382 | 383 | 384 | 385 | 387 | 388 | 392 | 393 | 398 | 399 | 401 | 403 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/adlcp_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for content packaging extensions. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2003-19-09 Removed the restriction of the 255 character maximum length 24 | on the dataFromLMS 25 | 2004-01-06 Added completionThreshold to the ADL CP namespace 26 | 2004-23-01 Final edits in preparation for release 27 | 2006-02-06 Removed persistState, change type of the locationType from 28 | xs:string to xs:anyURI 29 | ************************************************************************* 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/adlnav_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for navigation controls. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2004-23-01 Final edits in preparation for release 24 | 2005-06-06 Added new hideLMSUI vocabulary token suspendAll, exitAll, 25 | and abandonAll 26 | ************************************************************************* 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/adlseq_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for sequencing extensions. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2004-23-01 Final edits in preparation for release 24 | ************************************************************************* 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/datatypes.dtd: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 69 | 70 | 80 | 81 | 82 | 83 | 84 | 85 | 88 | 89 | 92 | 93 | 94 | 96 | 101 | 102 | 106 | 110 | 119 | 120 | 124 | 128 | 129 | 133 | 137 | 138 | 139 | 143 | 144 | 148 | 149 | 150 | 154 | 155 | 159 | 160 | 161 | 165 | 166 | 170 | 171 | 172 | 176 | 177 | 181 | 182 | 186 | 187 | 188 | 189 | 192 | 193 | 194 | 198 | 199 | 200 | 201 | 204 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 71 | 72 | The root element for all sequencing tags. This tag will usually appear as a child element to an IMS CP item tag. 73 | 74 | 75 | 76 | 77 | The type associated with any top-level sequencing tag 78 | 79 | 80 | 82 | 83 | non-exclusive definition of acceptable control-modes 84 | 85 | 86 | 88 | 90 | 92 | 94 | 96 | 102 | 103 | 105 | 107 | 108 | 109 | 110 | 111 | 112 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0auxresource.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0control.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | The type associated with a control-mode element (see the element controlMode) 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0delivery.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | The type that describes any element which fullfills a delivery control semantic 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0limit.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | Limit Condition Attempt Limit 66 | 67 | 68 | 69 | 70 | Limit Condition Activity Attempt Absolute Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 71 | 72 | 73 | 74 | 75 | Limit Condition Activity Attempt Experienced Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 76 | 77 | 78 | 79 | 80 | Limit Condition Activity Absolute Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 81 | 82 | 83 | 84 | 85 | Limit Condition Activity Experienced Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 86 | 87 | 88 | 89 | 90 | Limit Condition Begin Time Limit 91 | 92 | 93 | 94 | 95 | Limit Condition End Time Limit 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0objective.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | The specification states: "Each activity must have one and only one objective that contributes to rollup". The following type describes an unbounded set of elements all named "objective" that do not contribute to rollup, and one element called "primaryObjective" that contributes to rollup. 80 | 81 | 82 | 84 | 85 | Contributes to rollup of the activity. 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 97 | 98 | Does not contribute to the rollup of the activity. 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | The type that describes an individual objective mapping. Mapping one local objective GUID to one global objective GUID 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0random.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0rollup.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 66 | 67 | 68 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0seqrule.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | postConditionSequencingRuleType is derived by extension from sequencingRuleType. It adds an element ruleAction that is a simpleType constrained to a vocabulary relevant to post-Condition sequencing rules 79 | 80 | 81 | 82 | 83 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 111 | 112 | 113 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 132 | 134 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/imsss_v1p0util.xsd: -------------------------------------------------------------------------------- 1 | 2 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | A decimal value with AT LEAST 4 significant decimal digits between -1 and 1 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20043rdedition/xml.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | See http://www.w3.org/XML/1998/namespace.html and 8 | http://www.w3.org/TR/REC-xml for information about this namespace. 9 | 10 | 11 | 12 | 13 | This schema defines attributes and an attribute group 14 | suitable for use by 15 | schemas wishing to allow xml:base, xml:lang or xml:space attributes 16 | on elements they define. 17 | 18 | To enable this, such a schema must import this schema 19 | for the XML namespace, e.g. as follows: 20 | <schema . . .> 21 | . . . 22 | <import namespace="http://www.w3.org/XML/1998/namespace" 23 | schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> 24 | 25 | Subsequently, qualified reference to any of the attributes 26 | or the group defined below will have the desired effect, e.g. 27 | 28 | <type . . .> 29 | . . . 30 | <attributeGroup ref="xml:specialAttrs"/> 31 | 32 | will define a type which will schema-validate an instance 33 | element with any of those attributes 34 | 35 | 36 | 37 | In keeping with the XML Schema WG's standard versioning 38 | policy, this schema document will persist at 39 | http://www.w3.org/2001/03/xml.xsd. 40 | At the date of issue it can also be found at 41 | http://www.w3.org/2001/xml.xsd. 42 | The schema document at that URI may however change in the future, 43 | in order to remain compatible with the latest version of XML Schema 44 | itself. In other words, if the XML Schema namespace changes, the version 45 | of this document at 46 | http://www.w3.org/2001/xml.xsd will change 47 | accordingly; the version at 48 | http://www.w3.org/2001/03/xml.xsd will not change. 49 | 50 | 51 | 52 | 53 | 54 | In due course, we should install the relevant ISO 2- and 3-letter 55 | codes as the enumerated possible values . . . 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | See http://www.w3.org/TR/xmlbase/ for 71 | information about this attribute. 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/adlcp_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for content packaging extensions. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2003-19-09 Removed the restriction of the 255 character maximum length 24 | on the dataFromLMS 25 | 2004-01-06 Added completionThreshold to the ADL CP namespace 26 | 2004-23-01 Final edits in preparation for release 27 | 2006-02-06 Removed persistState, change type of the locationType from 28 | xs:string to xs:anyURI 29 | 2008-03-12 Removed the 0.0 to 1.0 restrictions from the 30 | completionThreshold element 31 | 2008-03-12 Added completedByMeasure, minProgressMeasure, and 32 | progressWeight attributes to completionThreshold element 33 | type 34 | 2009-30-01 Added the data element, map element and sharedDataGlobalToSystem attribute 35 | ************************************************************************* 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/adlnav_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for navigation controls. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2004-23-01 Final edits in preparation for release 24 | 2005-06-06 Added new hideLMSUI vocabulary token suspendAll, exitAll, 25 | and abandonAll 26 | ************************************************************************* 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/adlseq_v1p3.xsd: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | This file represents the W3C XML Schema Language Binding of the ADL namespaced elements for sequencing extensions. 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ************************************************************************* 20 | * Change History * 21 | ************************************************************************* 22 | 2003-18-09 Initial creation. 23 | 2004-23-01 Final edits in preparation for release 24 | 2008-15-12 Added data, map, objectives, objective and mapInfo elements 25 | and sharedDataGlobalToSystem attribute. 26 | 2009-30-01 Removed the data element, map element and 27 | sharedDataGlobalToSystem attribute. 28 | ************************************************************************* 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/datatypes.dtd: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 69 | 70 | 80 | 81 | 82 | 83 | 84 | 85 | 88 | 89 | 92 | 93 | 94 | 96 | 101 | 102 | 106 | 110 | 119 | 120 | 124 | 128 | 129 | 133 | 137 | 138 | 139 | 143 | 144 | 148 | 149 | 150 | 154 | 155 | 159 | 160 | 161 | 165 | 166 | 170 | 171 | 172 | 176 | 177 | 181 | 182 | 186 | 187 | 188 | 189 | 192 | 193 | 194 | 198 | 199 | 200 | 201 | 204 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 19 | The root element for all sequencing tags. This tag will usually appear as a child element to an IMS CP item tag. 20 | 21 | 22 | 23 | 24 | The type associated with any top-level sequencing tag 25 | 26 | 27 | 29 | 30 | non-exclusive definition of acceptable control-modes 31 | 32 | 33 | 35 | 37 | 39 | 41 | 43 | 49 | 50 | 52 | 54 | 55 | 56 | 57 | 58 | 59 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0auxresource.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0control.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | The type associated with a control-mode element (see the element controlMode) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0delivery.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | The type that describes any element which fullfills a delivery control semantic 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0limit.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | Limit Condition Attempt Limit 13 | 14 | 15 | 16 | 17 | Limit Condition Activity Attempt Absolute Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 18 | 19 | 20 | 21 | 22 | Limit Condition Activity Attempt Experienced Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 23 | 24 | 25 | 26 | 27 | Limit Condition Activity Absolute Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 28 | 29 | 30 | 31 | 32 | Limit Condition Activity Experienced Duration Limit. Typed as xs:duration: see http://www.w3.org/TR/xmlschema-2/#duration 33 | 34 | 35 | 36 | 37 | Limit Condition Begin Time Limit 38 | 39 | 40 | 41 | 42 | Limit Condition End Time Limit 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0objective.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | The specification states: "Each activity must have one and only one objective that contributes to rollup". The following type describes an unbounded set of elements all named "objective" that do not contribute to rollup, and one element called "primaryObjective" that contributes to rollup. 27 | 28 | 29 | 31 | 32 | Contributes to rollup of the activity. 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 45 | Does not contribute to the rollup of the activity. 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | The type that describes an individual objective mapping. Mapping one local objective GUID to one global objective GUID 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0random.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0rollup.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0seqrule.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | postConditionSequencingRuleType is derived by extension from sequencingRuleType. It adds an element ruleAction that is a simpleType constrained to a vocabulary relevant to post-Condition sequencing rules 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 58 | 59 | 60 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 79 | 81 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/imsss_v1p0util.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | A decimal value with AT LEAST 4 significant decimal digits between -1 and 1 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/schemas/definitionFiles/scorm20044thedition/xml.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | See http://www.w3.org/XML/1998/namespace.html and 8 | http://www.w3.org/TR/REC-xml for information about this namespace. 9 | 10 | 11 | 12 | 13 | This schema defines attributes and an attribute group 14 | suitable for use by 15 | schemas wishing to allow xml:base, xml:lang or xml:space attributes 16 | on elements they define. 17 | 18 | To enable this, such a schema must import this schema 19 | for the XML namespace, e.g. as follows: 20 | <schema . . .> 21 | . . . 22 | <import namespace="http://www.w3.org/XML/1998/namespace" 23 | schemaLocation="http://www.w3.org/2001/03/xml.xsd"/> 24 | 25 | Subsequently, qualified reference to any of the attributes 26 | or the group defined below will have the desired effect, e.g. 27 | 28 | <type . . .> 29 | . . . 30 | <attributeGroup ref="xml:specialAttrs"/> 31 | 32 | will define a type which will schema-validate an instance 33 | element with any of those attributes 34 | 35 | 36 | 37 | In keeping with the XML Schema WG's standard versioning 38 | policy, this schema document will persist at 39 | http://www.w3.org/2001/03/xml.xsd. 40 | At the date of issue it can also be found at 41 | http://www.w3.org/2001/xml.xsd. 42 | The schema document at that URI may however change in the future, 43 | in order to remain compatible with the latest version of XML Schema 44 | itself. In other words, if the XML Schema namespace changes, the version 45 | of this document at 46 | http://www.w3.org/2001/xml.xsd will change 47 | accordingly; the version at 48 | http://www.w3.org/2001/03/xml.xsd will not change. 49 | 50 | 51 | 52 | 53 | 54 | In due course, we should install the relevant ISO 2- and 3-letter 55 | codes as the enumerated possible values . . . 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | See http://www.w3.org/TR/xmlbase/ for 71 | information about this attribute. 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /lib/schemas/metadata.js: -------------------------------------------------------------------------------- 1 | var guid = require("../guid.js"); 2 | 3 | var EOL = "\r\n"; 4 | var vcard = function(data, exclude) { 5 | var exclude = exclude || {}; 6 | var card = "BEGIN:VCARD" + EOL; 7 | card += "VERSION:2.1" + EOL; 8 | if (data) { 9 | if (data.author) card += "FN:" + data.author + EOL; 10 | if (data.version && !exclude.version) 11 | card += "NOTE:version " + data.version + " " + EOL; 12 | if (data.org && !exclude.org) card += "ORG:" + data.org + EOL; 13 | if (data.tel && !exclude.tel && data.tel.length > 0) 14 | card += "TEL;WORK;VOICE:" + data.tel.join(";") + EOL; 15 | if (data.address && !exclude.address && data.address.length > 0) 16 | card += "ADR;WORK:;;" + data.address.join(";") + EOL; 17 | if (data.mail && !exclude.mail && data.mail.length > 0) 18 | card += "EMAIL;PREF;INTERNET:" + data.mail.join(";") + EOL; 19 | if (data.url && !exclude.url) card += "URL:" + data.url + EOL; 20 | } 21 | card += "END:VCARD "; 22 | return card; 23 | }; 24 | 25 | var vrequirements = function(data) { 26 | let arr = []; 27 | if (data.length) { 28 | for (var k = 0, n = data.length; k < n; k += 1) { 29 | var dataBlock = data[k]; 30 | if (dataBlock["type"] && dataBlock["name"]) { 31 | var block = { 32 | type: { 33 | source: { 34 | "#text": "LOMv1.0" 35 | }, 36 | value: { 37 | "#cdata": dataBlock.type 38 | } 39 | }, 40 | name: { 41 | source: { 42 | "#text": "LOMv1.0" 43 | }, 44 | value: { 45 | "#cdata": dataBlock.name 46 | } 47 | }, 48 | minimumversion: { 49 | "#cdata": dataBlock.version || "" 50 | } 51 | }; 52 | arr.push(block); 53 | } 54 | } 55 | } 56 | return arr; 57 | }; 58 | 59 | var keywords = function(data, lng) { 60 | let arr = []; 61 | for (var k = 0, n = data.length; k < n; k += 1) { 62 | arr.push({ 63 | string: { 64 | "@language": lng, 65 | "#cdata": data[k] 66 | } 67 | }); 68 | } 69 | return arr; 70 | }; 71 | 72 | module.exports = function(obj) { 73 | var name = obj.package.name, identifier = guid(obj); 74 | return { 75 | "@xmlns": "http://ltsc.ieee.org/xsd/LOM", 76 | "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 77 | "@xmlns:pkgprop": "http://www.scorm.com/xsd/ScormEnginePackageProperties", 78 | "@xsi:schemaLocation": "http://ltsc.ieee.org/xsd/LOM lomLoose.xsd " + 79 | "http://www.scorm.com/xsd/ScormEnginePackageProperties " + 80 | "ScormEnginePackageProperties.xsd", 81 | metametadata: { 82 | metadataSchema: ["LOMv1.0", "ADL SCORM " + obj.version], 83 | identifier: { 84 | catalog: "URI", 85 | entry: identifier 86 | }, 87 | language: { 88 | "#text": obj.language 89 | }, 90 | contribute: { 91 | role: { 92 | source: { 93 | "#text": "LOMv1.0" 94 | }, 95 | value: { 96 | "#text": "Creator" 97 | } 98 | }, 99 | entity: { 100 | "#cdata": vcard(obj.package.vcard, { 101 | version: true 102 | }) 103 | }, 104 | date: { 105 | dateTime: obj.package.date, 106 | description: { 107 | "@language": obj.language, 108 | "#cdata": obj.package.timestamp 109 | } 110 | } 111 | } 112 | }, 113 | general: { 114 | identifier: { 115 | catalog: "URI", 116 | entry: identifier 117 | }, 118 | title: { 119 | string: { 120 | "@language": obj.language, 121 | "#cdata": name 122 | } 123 | }, 124 | language: { 125 | "#text": obj.language 126 | }, 127 | description: { 128 | string: { 129 | "@language": obj.language, 130 | "#cdata": obj.package.description 131 | } 132 | }, 133 | structure: { 134 | source: { 135 | "#text": "LOMv1.0" 136 | }, 137 | value: { 138 | "#text": "atomic" 139 | } 140 | }, 141 | aggregationLevel: { 142 | source: { 143 | "#text": "LOMv1.0" 144 | }, 145 | value: { 146 | "#text": "1" 147 | } 148 | }, 149 | keyword: keywords(obj.package.keywords, obj.language) 150 | }, 151 | lifeCycle: { 152 | version: { 153 | string: { 154 | "@language": obj.language, 155 | "#text": obj.package.version 156 | } 157 | }, 158 | status: { 159 | source: "LOMv1.0", 160 | value: obj.package.status 161 | }, 162 | contribute: [ 163 | { 164 | entity: { 165 | "#cdata": vcard(obj.package.vcard, { 166 | version: true 167 | }) 168 | }, 169 | date: { 170 | dateTime: obj.package.date, 171 | description: { 172 | "@language": obj.language, 173 | "#cdata": obj.package.timestamp 174 | } 175 | } 176 | }, 177 | { 178 | role: { 179 | source: { 180 | "#text": "LOMv1.0" 181 | }, 182 | value: { 183 | "#text": "Author" 184 | } 185 | }, 186 | entity: { 187 | "#cdata": vcard(obj.package.vcard, { 188 | version: true 189 | }) 190 | }, 191 | date: { 192 | dateTime: obj.package.date, 193 | description: { 194 | "@language": obj.language, 195 | "#cdata": obj.package.timestamp 196 | } 197 | } 198 | }, 199 | { 200 | role: { 201 | source: { 202 | "#text": "LOMv1.0" 203 | }, 204 | value: { 205 | "#text": "Publisher" 206 | } 207 | }, 208 | entity: { 209 | "#cdata": vcard(obj.package.vcard) 210 | }, 211 | date: { 212 | dateTime: obj.package.date, 213 | description: { 214 | "@language": obj.language, 215 | "#cdata": obj.package.timestamp 216 | } 217 | } 218 | }, 219 | { 220 | role: { 221 | source: { 222 | "#text": "LOMv1.0" 223 | }, 224 | value: { 225 | "#text": "Technical Implementer" 226 | } 227 | }, 228 | entity: { 229 | "#cdata": vcard(obj.package.vcard, { 230 | version: true 231 | }) 232 | }, 233 | date: { 234 | dateTime: obj.package.date, 235 | description: { 236 | "@language": obj.language, 237 | "#cdata": obj.package.timestamp 238 | } 239 | } 240 | } 241 | ] 242 | }, 243 | technical: { 244 | format: ["text/html", "application/x-javascript", "text/css"], 245 | size: obj.package.size, 246 | location: obj.startingPage, 247 | requirement: vrequirements(obj.package.requirements), 248 | duration: { 249 | duration: obj.package.duration, 250 | description: { 251 | string: { 252 | "@language": obj.language, 253 | "#cdata": "The time it will take to watch the entire module from start to finish." 254 | } 255 | } 256 | }, 257 | "pkgprop:ScormEnginePackageProperties": { 258 | "@xmlns": "http://www.scorm.com/xsd/ScormEnginePackageProperties", 259 | appearance: { 260 | displayStage: { 261 | desired: { 262 | width: 1280, 263 | height: 720, 264 | fullscreen: "yes" 265 | }, 266 | required: { 267 | width: 300, 268 | height: 300, 269 | fullscreen: "no" 270 | } 271 | } 272 | }, 273 | behavior: { 274 | alwaysFlowToFirstSco: "yes", 275 | rollupEmptySetToUnknown: "yes" 276 | } 277 | } 278 | }, 279 | educational: { 280 | typicalLearningTime: { 281 | duration: obj.package.typicalDuration, 282 | description: { 283 | string: { 284 | "@language": obj.language, 285 | "#cdata": "The average time for a learner to complete this course." 286 | } 287 | } 288 | }, 289 | description: { 290 | string: { 291 | "#cdata": obj.package.educational 292 | } 293 | }, 294 | language: { 295 | "#text": obj.language 296 | } 297 | }, 298 | rights: { 299 | copyrightAndOtherRestrictions: { 300 | source: "LOMv1.0", 301 | value: "no" 302 | }, 303 | description: { 304 | string: { 305 | "@language": obj.language, 306 | "#cdata": obj.package.rights 307 | } 308 | } 309 | } 310 | }; 311 | }; 312 | -------------------------------------------------------------------------------- /lib/schemas/scorm12.js: -------------------------------------------------------------------------------- 1 | var guid = require("../guid.js"); 2 | module.exports = function(obj) { 3 | var identifier = guid(obj), 4 | itemIdentifier = "item_" + identifier, 5 | identifierref = "resource_" + identifier, 6 | organization = obj.organization.replace(/ /g, "_"); 7 | if (obj.identifier) { 8 | if (obj.identifier.trim()) { 9 | var ri = obj.identifier.replace(/ /g, ""); 10 | identifier = ri; 11 | itemIdentifier = "item_" + ri; 12 | identifierref = "resource_" + ri; 13 | } 14 | } 15 | return { 16 | "@identifier": identifier, 17 | "@version": 1, 18 | "@xmlns:adlcp": "http://www.adlnet.org/xsd/adlcp_rootv1p2", 19 | "@xmlns": "http://www.imsproject.org/xsd/imscp_rootv1p1p2", 20 | "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 21 | "@xsi:schemaLocation": "http://www.imsproject.org/xsd/imscp_rootv1p1p2 imscp_rootv1p1p2.xsd " + 22 | "http://www.imsglobal.org/xsd/imsmd_rootv1p2p1 imsmd_rootv1p2p1.xsd " + 23 | "http://www.adlnet.org/xsd/adlcp_rootv1p2 adlcp_rootv1p2.xsd", 24 | metadata: { 25 | schema: "ADL SCORM", 26 | schemaversion: obj.version, 27 | "adlcp:location": "metadata.xml" 28 | }, 29 | organizations: { 30 | "@default": organization, 31 | organization: { 32 | "@identifier": organization, 33 | title: obj.title, 34 | item: { 35 | "@identifier": itemIdentifier, 36 | "@identifierref": identifierref, 37 | title: obj.title, 38 | "adlcp:masteryscore": obj.masteryScore, 39 | metadata: { 40 | schema: "ADL SCORM", 41 | schemaversion: obj.version, 42 | "adlcp:location": "metadata.xml" 43 | } 44 | }, 45 | metadata: { 46 | schema: "ADL SCORM", 47 | schemaversion: obj.version, 48 | "adlcp:location": "metadata.xml" 49 | } 50 | } 51 | }, 52 | resources: { 53 | metadata: { 54 | schema: "ADL SCORM", 55 | schemaversion: obj.version, 56 | "adlcp:location": "metadata.xml" 57 | }, 58 | resource: { 59 | "@identifier": identifierref, 60 | "@type": "webcontent", 61 | "@href": obj.startingPage, 62 | "@adlcp:scormtype": "sco", 63 | metadata: { 64 | schema: "ADL SCORM", 65 | schemaversion: obj.version, 66 | "adlcp:location": "metadata.xml" 67 | }, 68 | file: obj.files 69 | } 70 | } 71 | }; 72 | }; 73 | -------------------------------------------------------------------------------- /lib/schemas/scorm2004.js: -------------------------------------------------------------------------------- 1 | var guid = require("../guid.js"); 2 | module.exports = function(obj) { 3 | var identifier = guid(obj), 4 | itemIdentifier = "item_" + identifier, 5 | identifierref = "resource_" + identifier, 6 | organization = obj.organization.replace(/ /g, "_"); 7 | if (obj.identifier) { 8 | if (obj.identifier.trim()) { 9 | var ri = obj.identifier.replace(/ /g, ""); 10 | identifier = ri; 11 | itemIdentifier = "item_" + ri; 12 | identifierref = "resource_" + ri; 13 | } 14 | } 15 | return { 16 | "@identifier": identifier, 17 | "@version": 1, 18 | "@xmlns:adlnav": "http://www.adlnet.org/xsd/adlnav_v1p3", 19 | "@xmlns": "http://www.imsglobal.org/xsd/imscp_v1p1", 20 | "@xmlns:adlseq": "http://www.adlnet.org/xsd/adlseq_v1p3", 21 | "@xmlns:imsss": "http://www.imsglobal.org/xsd/imsss", 22 | "@xmlns:adlcp": "http://www.adlnet.org/xsd/adlcp_v1p3", 23 | "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", 24 | "@xsi:schemaLocation": "http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd " + 25 | "http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd " + 26 | "http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd " + 27 | "http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd " + 28 | "http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd", 29 | metadata: { 30 | schema: "ADL SCORM", 31 | schemaversion: obj.version, 32 | "adlcp:location": "metadata.xml" 33 | }, 34 | organizations: { 35 | "@default": organization, 36 | organization: { 37 | "@identifier": organization, 38 | title: obj.title, 39 | item: { 40 | "@identifier": itemIdentifier, 41 | "@identifierref": identifierref, 42 | title: obj.title, 43 | "imsss:sequencing": { 44 | "imsss:objectives": { 45 | "imsss:primaryObjective": { 46 | "@objectiveID": "PRIMARYOBJ", 47 | "@satisfiedByMeasure": "true", 48 | "imsss:minNormalizedMeasure": obj.masteryScore / 100 49 | } 50 | }, 51 | "imsss:deliveryControls": { 52 | "@completionSetByContent": "true", 53 | "@objectiveSetByContent": "true" 54 | } 55 | }, 56 | metadata: { 57 | schema: "ADL SCORM", 58 | schemaversion: obj.version, 59 | "adlcp:location": "metadata.xml" 60 | } 61 | }, 62 | metadata: { 63 | schema: "ADL SCORM", 64 | schemaversion: obj.version, 65 | "adlcp:location": "metadata.xml" 66 | }, 67 | "imsss:sequencing": { 68 | "imsss:controlMode": { 69 | "@choice": "true", 70 | "@flow": "true" 71 | } 72 | } 73 | } 74 | }, 75 | resources: { 76 | metadata: { 77 | schema: "ADL SCORM", 78 | schemaversion: obj.version, 79 | "adlcp:location": "metadata.xml" 80 | }, 81 | resource: { 82 | "@identifier": identifierref, 83 | "@type": "webcontent", 84 | "@href": obj.startingPage, 85 | "@adlcp:scormType": "sco", 86 | metadata: { 87 | schema: "ADL SCORM", 88 | schemaversion: obj.version, 89 | "adlcp:location": "metadata.xml" 90 | }, 91 | file: obj.files 92 | } 93 | } 94 | }; 95 | }; 96 | -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | module.exports = { 3 | cleanAndTrim: function(text) { 4 | //Escape all non alphanum characters 5 | // a;s,ç!('d123[שץ,דתג] => asçd123שץדתג 6 | var textClean = text.replace(/[^\p{L}0-9]+/gu, ""); 7 | return textClean.replace(/\s/g, ""); 8 | }, 9 | acronym: function(words) { 10 | if (!words) { 11 | return ""; 12 | } 13 | var first_letter = function(x) { 14 | if (x) { 15 | return x[0]; 16 | } else { 17 | return ""; 18 | } 19 | }; 20 | return words.split(" ").map(first_letter).join(""); 21 | }, 22 | uuid: function() { 23 | var now = new Date(); 24 | var d = now.getTime(); 25 | var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace( 26 | /[xy]/g, 27 | function(c) { 28 | var r = (d + Math.random() * 16) % 16 | 0; 29 | d = Math.floor(d / 16); 30 | return (c == "x" ? r : r & 0x3 | 0x8).toString(16); 31 | } 32 | ); 33 | return uuid; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-scorm-packager", 3 | "version": "0.2.7", 4 | "description": "Simple way to package your scorm projects", 5 | "main": "lib/index.js", 6 | "bin": { 7 | "simple-scorm-packager": "./cli.js", 8 | "scopackager": "./cli.js" 9 | }, 10 | "preferGlobal": true, 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/lmihaidaniel/simple-scorm-packager.git" 17 | }, 18 | "keywords": [ 19 | "lms", 20 | "scorm", 21 | "manifest", 22 | "interactive", 23 | "package" 24 | ], 25 | "author": "lmihaidaniel ", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/lmihaidaniel/simple-scorm-packager/issues" 29 | }, 30 | "homepage": "https://github.com/lmihaidaniel/simple-scorm-packager#readme", 31 | "dependencies": { 32 | "archiver": "^5.3.1", 33 | "fs-extra": "^10.1.0", 34 | "inquirer": "^8.2.4", 35 | "inquirer-directory": "^2.2.0", 36 | "jsonschema": "^1.4.1", 37 | "xmlbuilder": "^15.1.1" 38 | } 39 | } 40 | --------------------------------------------------------------------------------