adapt-migrations 1.0.0 → 1.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/.eslintignore CHANGED
@@ -1 +1 @@
1
- node_modules
1
+ node_modules
package/.eslintrc.json CHANGED
@@ -1,14 +1,14 @@
1
- {
2
- "env": {
3
- "browser": false,
4
- "node": true,
5
- "commonjs": false,
6
- "es2020": true
7
- },
8
- "extends": [
9
- "standard"
10
- ],
11
- "parserOptions": {
12
- "ecmaVersion": 2022
13
- }
14
- }
1
+ {
2
+ "env": {
3
+ "browser": false,
4
+ "node": true,
5
+ "commonjs": false,
6
+ "es2020": true
7
+ },
8
+ "extends": [
9
+ "standard"
10
+ ],
11
+ "parserOptions": {
12
+ "ecmaVersion": 2022
13
+ }
14
+ }
package/README.md CHANGED
@@ -1,43 +1,43 @@
1
- # adapt-migrations
2
-
3
- ### Todos
4
- https://github.com/cgkineo/adapt-migrations/issues/1
5
-
6
- ### Commands API
7
- https://github.com/cgkineo/adapt-migrations/blob/master/api/commands.js
8
- * `load({ cwd, cachePath, scripts })` - loads all migration tasks
9
- * `capture({ cwd, content, fromPlugins })` - captures current plugins and content
10
- * `migrate({ cwd, toPlugins })` - migrates content from capture to new plugins
11
- * `test({ cwd })` - tests the migrations with dummy content
12
-
13
- ### Migration script API
14
- Functions:
15
- * `describe(description, describeFunction)` Describe a migration
16
- * `whereContent(description, contentFilterFunction)` Limit when the migration runs, return true/false/throw Error
17
- * `whereFromPlugin(description, fromPluginFilterFunction)` Limit when the migration runs, return true/false/throw Error
18
- * `whereToPlugin(description, toPluginFilterFunction)` Limit when the migration runs, return true/false/throw Error
19
- * `mutateContent(contentFunction)` Change content, return true/false/throw Error
20
- * `checkContent(contentFunction)` Check content, return true/false/throw Error
21
- * `throwError(description)` Throw an error
22
- * `testSuccessWhere({ fromPlugins, toPlugins, content })` Supply some tests content which should end in success
23
- * `testStopWhere({ fromPlugins, toPlugins, content })` Supply some tests content which should end prematurely
24
- * `testErrorWhere({ fromPlugins, toPlugins, content })` Supply some tests content which will trigger an error
25
-
26
- Arguments:
27
- * `describeFunction = () => {}` Function body has a collection of migration script functions
28
- * `contentFilterFunction = content => {}` Function body should return true/false/throw Error
29
- * `fromPluginFilterFunction = fromPlugins => {}` Function body should return true/false/throw Error
30
- * `toPluginFilterFunction = toPlugins => {}` Function body should return true/false/throw Error
31
- * `contentFunction = content => { }` Function body should mutate or check the content, returning true/false/throw Error
32
- * `fromPlugins = [{ name: 'quickNav , version: '1.0.0' }]` Test data describing the original plugins
33
- * `toPlugins = [{ name: 'pageNav , version: '1.0.0' }]` Test data describing the destination plugins
34
- * `content = [{ _id: 'c-05, ... }]` Test content for the course content
35
-
36
- ### Grunt Commands
37
- ```sh
38
- grunt migration:capture # captures current plugins and content
39
- # do plugin/fw updates
40
- grunt migration:migrate # migrates content from capture to new plugins
41
- grunt migration:test # tests the migrations with dummy content
42
- grunt migration:test --file=adapt-contrib-text/migrations/text.js # tests the migrations with dummy content
43
- ```
1
+ # adapt-migrations
2
+
3
+ ### Todos
4
+ https://github.com/cgkineo/adapt-migrations/issues/1
5
+
6
+ ### Commands API
7
+ https://github.com/cgkineo/adapt-migrations/blob/master/api/commands.js
8
+ * `load({ cwd, cachePath, scripts })` - loads all migration tasks
9
+ * `capture({ cwd, content, fromPlugins })` - captures current plugins and content
10
+ * `migrate({ cwd, toPlugins })` - migrates content from capture to new plugins
11
+ * `test({ cwd })` - tests the migrations with dummy content
12
+
13
+ ### Migration script API
14
+ Functions:
15
+ * `describe(description, describeFunction)` Describe a migration
16
+ * `whereContent(description, contentFilterFunction)` Limit when the migration runs, return true/false/throw Error
17
+ * `whereFromPlugin(description, fromPluginFilterFunction)` Limit when the migration runs, return true/false/throw Error
18
+ * `whereToPlugin(description, toPluginFilterFunction)` Limit when the migration runs, return true/false/throw Error
19
+ * `mutateContent(contentFunction)` Change content, return true/false/throw Error
20
+ * `checkContent(contentFunction)` Check content, return true/false/throw Error
21
+ * `throwError(description)` Throw an error
22
+ * `testSuccessWhere({ fromPlugins, toPlugins, content })` Supply some tests content which should end in success
23
+ * `testStopWhere({ fromPlugins, toPlugins, content })` Supply some tests content which should end prematurely
24
+ * `testErrorWhere({ fromPlugins, toPlugins, content })` Supply some tests content which will trigger an error
25
+
26
+ Arguments:
27
+ * `describeFunction = () => {}` Function body has a collection of migration script functions
28
+ * `contentFilterFunction = content => {}` Function body should return true/false/throw Error
29
+ * `fromPluginFilterFunction = fromPlugins => {}` Function body should return true/false/throw Error
30
+ * `toPluginFilterFunction = toPlugins => {}` Function body should return true/false/throw Error
31
+ * `contentFunction = content => { }` Function body should mutate or check the content, returning true/false/throw Error
32
+ * `fromPlugins = [{ name: 'quickNav , version: '1.0.0' }]` Test data describing the original plugins
33
+ * `toPlugins = [{ name: 'pageNav , version: '1.0.0' }]` Test data describing the destination plugins
34
+ * `content = [{ _id: 'c-05, ... }]` Test content for the course content
35
+
36
+ ### Grunt Commands
37
+ ```sh
38
+ grunt migration:capture # captures current plugins and content
39
+ # do plugin/fw updates
40
+ grunt migration:migrate # migrates content from capture to new plugins
41
+ grunt migration:test # tests the migrations with dummy content
42
+ grunt migration:test --file=adapt-contrib-text/migrations/text.js # tests the migrations with dummy content
43
+ ```
package/api/commands.js CHANGED
@@ -1,33 +1,33 @@
1
- import Task from '../lib/Task.js'
2
-
3
- export async function load ({ cwd = process.cwd(), scripts = [], cachePath, logger } = {}) {
4
- return Task.load({
5
- cwd,
6
- scripts,
7
- cachePath,
8
- logger
9
- })
10
- }
11
-
12
- export async function capture ({ content, fromPlugins, logger }) {
13
- return {
14
- content,
15
- fromPlugins,
16
- logger
17
- }
18
- };
19
-
20
- export async function migrate ({ cwd = process.cwd(), journal, logger }) {
21
- return Task.runApplicable({
22
- cwd,
23
- journal,
24
- logger
25
- })
26
- }
27
-
28
- export async function test ({ cwd = process.cwd(), logger } = {}) {
29
- return Task.runTests({
30
- cwd,
31
- logger
32
- })
33
- }
1
+ import Task from '../lib/Task.js'
2
+
3
+ export async function load ({ cwd = process.cwd(), scripts = [], cachePath, logger } = {}) {
4
+ return Task.load({
5
+ cwd,
6
+ scripts,
7
+ cachePath,
8
+ logger
9
+ })
10
+ }
11
+
12
+ export async function capture ({ content, fromPlugins, logger }) {
13
+ return {
14
+ content,
15
+ fromPlugins,
16
+ logger
17
+ }
18
+ };
19
+
20
+ export async function migrate ({ cwd = process.cwd(), journal, logger }) {
21
+ return Task.runApplicable({
22
+ cwd,
23
+ journal,
24
+ logger
25
+ })
26
+ }
27
+
28
+ export async function test ({ cwd = process.cwd(), logger } = {}) {
29
+ return Task.runTests({
30
+ cwd,
31
+ logger
32
+ })
33
+ }
package/api/data.js CHANGED
@@ -1,26 +1,26 @@
1
- import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
-
3
- export function mutateContent (description, callback) {
4
- return deferOrRunWrap(function (context) {
5
- return successStopOrErrorWrap('mutateContent', description, async () => {
6
- return callback(context.content)
7
- })
8
- }, { description, type: 'action' })
9
- };
10
-
11
- export function checkContent (description, callback) {
12
- return deferOrRunWrap(function (context) {
13
- return successStopOrErrorWrap('checkContent', description, async () => {
14
- context.journal.freeze()
15
- let result
16
- try {
17
- result = await callback(context.content)
18
- } catch (err) {
19
- context.journal.unfreeze()
20
- throw err
21
- }
22
- context.journal.unfreeze()
23
- return result
24
- })
25
- }, { description, type: 'action' })
26
- };
1
+ import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
+
3
+ export function mutateContent (description, callback) {
4
+ return deferOrRunWrap(function (context) {
5
+ return successStopOrErrorWrap('mutateContent', description, async () => {
6
+ return callback(context.content)
7
+ })
8
+ }, { description, type: 'action' })
9
+ };
10
+
11
+ export function checkContent (description, callback) {
12
+ return deferOrRunWrap(function (context) {
13
+ return successStopOrErrorWrap('checkContent', description, async () => {
14
+ context.journal.freeze()
15
+ let result
16
+ try {
17
+ result = await callback(context.content)
18
+ } catch (err) {
19
+ context.journal.unfreeze()
20
+ throw err
21
+ }
22
+ context.journal.unfreeze()
23
+ return result
24
+ })
25
+ }, { description, type: 'action' })
26
+ };
package/api/describe.js CHANGED
@@ -1,12 +1,12 @@
1
- import Task from '../lib/Task.js'
2
- import Logger from './../lib/Logger.js'
3
-
4
- export function describe (description, load) {
5
- const logger = Logger.getInstance();
6
- logger.info(`Describe -- ${description} -- Registered`)
7
- if (Task.current) {
8
- logger.error(`Describe -- Cannot nest describe statements -- ${description}`)
9
- }
10
- // eslint-disable-next-line no-new
11
- new Task({ description, load })
12
- };
1
+ import Task from '../lib/Task.js'
2
+ import Logger from './../lib/Logger.js'
3
+
4
+ export function describe (description, load) {
5
+ const logger = Logger.getInstance();
6
+ logger.info(`Describe -- ${description} -- Registered`)
7
+ if (Task.current) {
8
+ logger.error(`Describe -- Cannot nest describe statements -- ${description}`)
9
+ }
10
+ // eslint-disable-next-line no-new
11
+ new Task({ description, load })
12
+ };
package/api/errors.js CHANGED
@@ -1,28 +1,28 @@
1
- import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
- import Logger from './../lib/Logger.js'
3
-
4
- const logger = Logger.getInstance();
5
-
6
- export function throwError (description) {
7
- let error = description
8
- if (!(description instanceof Error)) {
9
- logger.error(`Errors -- ${description}`)
10
- error = new Error(description)
11
- } else {
12
- description = description.message
13
- }
14
- return deferOrRunWrap(function (context) {
15
- return successStopOrErrorWrap('throwError', description, async () => {
16
- throw error
17
- })
18
- }, { type: 'action' })
19
- }
20
-
21
- export function ifErroredAsk (config) {
22
- return deferOrRunWrap(function (context) {
23
- return successStopOrErrorWrap('isErroredAsk', config.question, async () => {
24
- if (!context.hasErrored) return true
25
- // Ask a question
26
- })
27
- }, { type: 'error' })
28
- };
1
+ import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
+ import Logger from './../lib/Logger.js'
3
+
4
+ const logger = Logger.getInstance();
5
+
6
+ export function throwError (description) {
7
+ let error = description
8
+ if (!(description instanceof Error)) {
9
+ logger.error(`Errors -- ${description}`)
10
+ error = new Error(description)
11
+ } else {
12
+ description = description.message
13
+ }
14
+ return deferOrRunWrap(function (context) {
15
+ return successStopOrErrorWrap('throwError', description, async () => {
16
+ throw error
17
+ })
18
+ }, { type: 'action' })
19
+ }
20
+
21
+ export function ifErroredAsk (config) {
22
+ return deferOrRunWrap(function (context) {
23
+ return successStopOrErrorWrap('isErroredAsk', config.question, async () => {
24
+ if (!context.hasErrored) return true
25
+ // Ask a question
26
+ })
27
+ }, { type: 'error' })
28
+ };
package/api/helpers.js ADDED
@@ -0,0 +1,17 @@
1
+ import Task from '../lib/Task.js'
2
+
3
+ function getContent() {
4
+ return Task.current.context.content;
5
+ }
6
+
7
+ export function getConfig () {
8
+ return getContent().find(({ _type, __path__ }) => _type === 'config' || __path__.endsWith('config.json'))
9
+ }
10
+
11
+ export function getCourse() {
12
+ return getContent().find(({ _type }) => _type === 'course');
13
+ }
14
+
15
+ export function getComponents(componentName) {
16
+ return getContent().filter(({ _component }) => _component === componentName);
17
+ }
package/api/plugins.js CHANGED
@@ -1,44 +1,47 @@
1
- import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
-
3
- export function removePlugin (description, config) {
4
- return deferOrRunWrap(function (context) {
5
- return successStopOrErrorWrap('removePlugin', description, async () => {
6
- if (!description || !config) throw new Error('removePlugin - incorrectly configured')
7
-
8
- context.fromPlugins = context.fromPlugins.filter(plugin => plugin.name !== config.name)
9
-
10
- return true
11
- })
12
- }, { description, type: 'action' })
13
- };
14
-
15
- export function addPlugin (description, config) {
16
- return deferOrRunWrap(function (context) {
17
- return successStopOrErrorWrap('addPlugin', description, async () => {
18
- if (!description || !config) throw new Error('addPlugin - incorrectly configured')
19
-
20
- const newPlugin = context.toPlugins.find(plugin => (plugin.name === config.name))
21
- if (!newPlugin) throw new Error(`addPlugin - ${config.name} not found`)
22
- context.fromPlugins.push(newPlugin)
23
-
24
- return true
25
- })
26
- }, { description, type: 'action' })
27
- };
28
-
29
- export function updatePlugin (description, config) {
30
- return deferOrRunWrap(function (context) {
31
- return successStopOrErrorWrap('updatePlugin', description, async () => {
32
- if (!description || !config) throw new Error('updatePlugin - incorrectly configured')
33
-
34
- context.fromPlugins.forEach(plugin => {
35
- if (plugin.name !== config.name) return
36
- plugin.version = config.version
37
- if (!config.framework) return
38
- plugin.framework = config.framework
39
- })
40
-
41
- return true
42
- })
43
- }, { description, type: 'action' })
44
- };
1
+ import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
2
+ const VERSION_CHECK = /^\d+\.\d+\.\d+$/
3
+
4
+ export function removePlugin (description, config) {
5
+ return deferOrRunWrap(function (context) {
6
+ return successStopOrErrorWrap('removePlugin', description, async () => {
7
+ if (!description || !config) throw new Error('removePlugin - incorrectly configured')
8
+
9
+ context.fromPlugins = context.fromPlugins.filter(plugin => plugin.name !== config.name)
10
+
11
+ return true
12
+ })
13
+ }, { description, type: 'action' })
14
+ };
15
+
16
+ export function addPlugin (description, config) {
17
+ return deferOrRunWrap(function (context) {
18
+ return successStopOrErrorWrap('addPlugin', description, async () => {
19
+ if (!description || !config) throw new Error('addPlugin - incorrectly configured')
20
+ if (!VERSION_CHECK.test(config.version)) throw new Error(`addPlugin - invalid version number ${config.version}`)
21
+
22
+ const newPlugin = context.toPlugins.find(plugin => (plugin.name === config.name))
23
+ if (!newPlugin) throw new Error(`addPlugin - ${config.name} not found`)
24
+ context.fromPlugins.push(newPlugin)
25
+
26
+ return true
27
+ })
28
+ }, { description, type: 'action' })
29
+ };
30
+
31
+ export function updatePlugin (description, config) {
32
+ return deferOrRunWrap(function (context) {
33
+ return successStopOrErrorWrap('updatePlugin', description, async () => {
34
+ if (!description || !config) throw new Error('updatePlugin - incorrectly configured')
35
+ if (!VERSION_CHECK.test(config.version)) throw new Error(`updatePlugin - invalid version number ${config.version}`)
36
+
37
+ context.fromPlugins.forEach(plugin => {
38
+ if (plugin.name !== config.name) return
39
+ plugin.version = config.version
40
+ if (!config.framework) return
41
+ plugin.framework = config.framework
42
+ })
43
+
44
+ return true
45
+ })
46
+ }, { description, type: 'action' })
47
+ };
package/api/tests.js CHANGED
@@ -1,57 +1,57 @@
1
- import TaskTest from '../lib/TaskTest.js'
2
- import { deferOrRunWrap } from '../lib/lifecycle.js'
3
- import Logger from '../lib/Logger.js'
4
-
5
- const logger = Logger.getInstance();
6
-
7
- export function testSuccessWhere (description, {
8
- fromPlugins,
9
- toPlugins,
10
- content
11
- }) {
12
- return deferOrRunWrap(() => {
13
- logger.debug(`Tests -- testSuccessWhere ${description}`)
14
- return new TaskTest({
15
- description,
16
- shouldRun: true,
17
- fromPlugins,
18
- toPlugins,
19
- content
20
- })
21
- }, { type: 'test' })
22
- };
23
-
24
- export function testStopWhere (description, {
25
- fromPlugins,
26
- toPlugins,
27
- content
28
- }) {
29
- return deferOrRunWrap(() => {
30
- logger.debug(`Tests -- testStopWhere ${description}`)
31
- return new TaskTest({
32
- description,
33
- shouldStop: true,
34
- shouldRun: false,
35
- fromPlugins,
36
- toPlugins,
37
- content
38
- })
39
- }, { type: 'test' })
40
- };
41
-
42
- export function testErrorWhere (description, {
43
- fromPlugins,
44
- toPlugins,
45
- content
46
- }) {
47
- return deferOrRunWrap(() => {
48
- logger.debug(`Tests -- testErrorWhere ${description}`)
49
- return new TaskTest({
50
- description,
51
- shouldError: true,
52
- fromPlugins,
53
- toPlugins,
54
- content
55
- })
56
- }, { type: 'test' })
57
- };
1
+ import TaskTest from '../lib/TaskTest.js'
2
+ import { deferOrRunWrap } from '../lib/lifecycle.js'
3
+ import Logger from '../lib/Logger.js'
4
+
5
+ const logger = Logger.getInstance();
6
+
7
+ export function testSuccessWhere (description, {
8
+ fromPlugins,
9
+ toPlugins,
10
+ content
11
+ }) {
12
+ return deferOrRunWrap(() => {
13
+ logger.debug(`Tests -- testSuccessWhere ${description}`)
14
+ return new TaskTest({
15
+ description,
16
+ shouldRun: true,
17
+ fromPlugins,
18
+ toPlugins,
19
+ content
20
+ })
21
+ }, { type: 'test' })
22
+ };
23
+
24
+ export function testStopWhere (description, {
25
+ fromPlugins,
26
+ toPlugins,
27
+ content
28
+ }) {
29
+ return deferOrRunWrap(() => {
30
+ logger.debug(`Tests -- testStopWhere ${description}`)
31
+ return new TaskTest({
32
+ description,
33
+ shouldStop: true,
34
+ shouldRun: false,
35
+ fromPlugins,
36
+ toPlugins,
37
+ content
38
+ })
39
+ }, { type: 'test' })
40
+ };
41
+
42
+ export function testErrorWhere (description, {
43
+ fromPlugins,
44
+ toPlugins,
45
+ content
46
+ }) {
47
+ return deferOrRunWrap(() => {
48
+ logger.debug(`Tests -- testErrorWhere ${description}`)
49
+ return new TaskTest({
50
+ description,
51
+ shouldError: true,
52
+ fromPlugins,
53
+ toPlugins,
54
+ content
55
+ })
56
+ }, { type: 'test' })
57
+ };
package/api/where.js CHANGED
@@ -1,46 +1,46 @@
1
- import semver from 'semver'
2
- import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
3
-
4
- export function whereContent (description, callback) {
5
- return deferOrRunWrap(({ content }) => {
6
- return successStopOrErrorWrap('whereContent', description, async () => {
7
- return callback(content)
8
- })
9
- }, { description, type: 'where' })
10
- };
11
-
12
- export function whereFromPlugin (description, callbackOrConfig) {
13
- return deferOrRunWrap(({ fromPlugins }) => {
14
- return successStopOrErrorWrap('whereFromPlugin', description, async () => {
15
- const isCallback = (typeof callbackOrConfig === 'function')
16
- if (isCallback) {
17
- const callback = callbackOrConfig
18
- return callback(fromPlugins)
19
- }
20
- const config = callbackOrConfig
21
- return fromPlugins.some(plugin => {
22
- if (config.name && plugin.name !== config.name) return false
23
- if (config.version && !semver.satisfies(plugin.version, config.version)) return false
24
- return true
25
- })
26
- })
27
- }, { description, type: 'where' })
28
- };
29
-
30
- export function whereToPlugin (description, callbackOrConfig) {
31
- return deferOrRunWrap(({ toPlugins }) => {
32
- return successStopOrErrorWrap('whereToPlugin', description, async () => {
33
- const isCallback = (typeof callbackOrConfig === 'function')
34
- if (isCallback) {
35
- const callback = callbackOrConfig
36
- return callback(toPlugins)
37
- }
38
- const config = callbackOrConfig
39
- return toPlugins.some(plugin => {
40
- if (config.name && plugin.name !== config.name) return false
41
- if (config.version && !semver.satisfies(plugin.version, config.version)) return false
42
- return true
43
- })
44
- })
45
- }, { description, type: 'where' })
46
- };
1
+ import semver from 'semver'
2
+ import { deferOrRunWrap, successStopOrErrorWrap } from '../lib/lifecycle.js'
3
+
4
+ export function whereContent (description, callback) {
5
+ return deferOrRunWrap(({ content }) => {
6
+ return successStopOrErrorWrap('whereContent', description, async () => {
7
+ return callback(content)
8
+ })
9
+ }, { description, type: 'where' })
10
+ };
11
+
12
+ export function whereFromPlugin (description, callbackOrConfig) {
13
+ return deferOrRunWrap(({ fromPlugins }) => {
14
+ return successStopOrErrorWrap('whereFromPlugin', description, async () => {
15
+ const isCallback = (typeof callbackOrConfig === 'function')
16
+ if (isCallback) {
17
+ const callback = callbackOrConfig
18
+ return callback(fromPlugins)
19
+ }
20
+ const config = callbackOrConfig
21
+ return fromPlugins.some(plugin => {
22
+ if (config.name && plugin.name !== config.name) return false
23
+ if (config.version && !semver.satisfies(plugin.version, config.version)) return false
24
+ return true
25
+ })
26
+ })
27
+ }, { description, type: 'where' })
28
+ };
29
+
30
+ export function whereToPlugin (description, callbackOrConfig) {
31
+ return deferOrRunWrap(({ toPlugins }) => {
32
+ return successStopOrErrorWrap('whereToPlugin', description, async () => {
33
+ const isCallback = (typeof callbackOrConfig === 'function')
34
+ if (isCallback) {
35
+ const callback = callbackOrConfig
36
+ return callback(toPlugins)
37
+ }
38
+ const config = callbackOrConfig
39
+ return toPlugins.some(plugin => {
40
+ if (config.name && plugin.name !== config.name) return false
41
+ if (config.version && !semver.satisfies(plugin.version, config.version)) return false
42
+ return true
43
+ })
44
+ })
45
+ }, { description, type: 'where' })
46
+ };