@sequencemedia/minimserver 0.1.27 → 1.2.2

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.
@@ -0,0 +1,4 @@
1
+ #!/bin/sh
2
+ . "$(dirname "$0")/_/husky.sh"
3
+
4
+ npm run pre-commit
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- require('dotenv/config')
3
+ import 'dotenv/config'
4
4
 
5
- const debug = require('debug')
5
+ import debug from 'debug'
6
6
 
7
- const psList = require('ps-list')
7
+ import {
8
+ readFile
9
+ } from 'fs/promises'
8
10
 
9
- const {
10
- execute
11
- } = require('./lib')
11
+ import psList from 'ps-list'
12
12
 
13
- const commander = require('commander')
13
+ import commander from 'commander'
14
14
 
15
- const PACKAGE = require('./package')
15
+ import minimServer from '#minimserver'
16
16
 
17
- const log = debug('minimserver')
17
+ const log = debug('@sequencemedia/minimserver')
18
18
 
19
19
  log('`minimserver` is awake')
20
20
 
@@ -22,6 +22,8 @@ const NAME = 'ms.App'
22
22
  process.title = NAME
23
23
 
24
24
  async function app () {
25
+ const PACKAGE = JSON.parse(await readFile('./package.json', 'utf8'))
26
+
25
27
  const {
26
28
  name
27
29
  } = PACKAGE
@@ -42,14 +44,14 @@ async function app () {
42
44
  pid
43
45
  } = a.find(({ pid }) => pid !== PID)
44
46
 
45
- const log = debug('minimserver:process:log')
47
+ const log = debug('@sequencemedia/minimserver:process')
46
48
 
47
49
  log(`Killing application "${name}" in process ${pid}.`)
48
50
 
49
51
  process.kill(pid)
50
52
  }
51
53
  } catch ({ message }) {
52
- const error = debug('minimserver:process:error')
54
+ const error = debug('@sequencemedia/minimserver:process:error')
53
55
 
54
56
  error(message)
55
57
  return
@@ -59,9 +61,6 @@ async function app () {
59
61
  pid,
60
62
  argv,
61
63
  env: {
62
- ORIGIN,
63
- DESTINATION,
64
- SERVER,
65
64
  IGNORE,
66
65
  BOUNCE
67
66
  }
@@ -88,7 +87,7 @@ async function app () {
88
87
  code
89
88
  } = e
90
89
 
91
- const error = debug('minimserver:commander:error')
90
+ const error = debug('@sequencemedia/minimserver:commander:error')
92
91
 
93
92
  if (code !== 'commander.missingMandatoryOptionValue') error(e)
94
93
 
@@ -97,9 +96,9 @@ async function app () {
97
96
  }
98
97
 
99
98
  const {
100
- origin = ORIGIN,
101
- destination = DESTINATION,
102
- server = SERVER,
99
+ origin,
100
+ destination,
101
+ server,
103
102
  ignore = IGNORE,
104
103
  bounce = BOUNCE
105
104
  } = commander.opts()
@@ -113,12 +112,12 @@ async function app () {
113
112
  })
114
113
 
115
114
  try {
116
- await execute(origin, destination, server, ignore, bounce)
115
+ await minimServer(origin, destination, server, ignore, bounce)
117
116
  } catch ({ message }) {
118
- const error = debug('minimserver:execute:error')
117
+ const error = debug('@sequencemedia/minimserver:error')
119
118
 
120
119
  error(message)
121
120
  }
122
121
  }
123
122
 
124
- module.exports = app()
123
+ export default app()
@@ -0,0 +1,21 @@
1
+ const presets = [
2
+ [
3
+ '@babel/env',
4
+ {
5
+ targets: {
6
+ node: 'current'
7
+ },
8
+ useBuiltIns: 'usage',
9
+ corejs: 3
10
+ }
11
+ ]
12
+ ]
13
+
14
+ const plugins = []
15
+
16
+ module.exports = {
17
+ compact: true,
18
+ comments: false,
19
+ presets,
20
+ plugins
21
+ }
@@ -0,0 +1,114 @@
1
+ import debug from 'debug'
2
+
3
+ import {
4
+ exec
5
+ } from 'child_process'
6
+
7
+ const log = debug('@sequencemedia/minimserver:build:gulp:pre-commit')
8
+
9
+ log('`@sequencemedia/minimserver` is awake')
10
+
11
+ const PACKAGE_VERSION_CHANGES = /\-+\s+"version":\s+"(\d+\.\d+\.\d+)",+\s+\++\s+"version":\s+"(\d+\.\d+\.\d+)",+\s+/ /* eslint-disable-line no-useless-escape */
12
+
13
+ const HAS_STAGED_CHANGES = /Changes to be committed/s
14
+
15
+ const NOT_STAGED_CHANGES = /Changes not staged for commit/s
16
+
17
+ const OPTIONS = {
18
+ maxBuffer: 1024 * 500
19
+ }
20
+
21
+ export function hasPackageVersionChanges () {
22
+ log('hasPackageVersionChanges')
23
+
24
+ return (
25
+ new Promise((resolve, reject) => {
26
+ exec('git diff HEAD origin/master package.json', OPTIONS, (e, v) => (!e) ? resolve(PACKAGE_VERSION_CHANGES.test(v)) : reject(e))
27
+ })
28
+ )
29
+ }
30
+
31
+ export function notPackageVersionChanges () {
32
+ log('notPackageVersionChanges')
33
+
34
+ return (
35
+ new Promise((resolve, reject) => {
36
+ exec('git diff HEAD origin/master package.json', OPTIONS, (e, v) => (!e) ? resolve(PACKAGE_VERSION_CHANGES.test(v) !== true) : reject(e))
37
+ })
38
+ )
39
+ }
40
+
41
+ export function hasStagedChanges () {
42
+ log('hasStagedChanges')
43
+
44
+ return (
45
+ new Promise((resolve, reject) => {
46
+ exec('git status', OPTIONS, (e, v) => (!e) ? resolve(HAS_STAGED_CHANGES.test(v)) : reject(e))
47
+ })
48
+ )
49
+ }
50
+
51
+ export function notStagedChanges () {
52
+ log('notStagedChanges')
53
+
54
+ return (
55
+ new Promise((resolve, reject) => {
56
+ exec('git status', OPTIONS, (e, v) => (!e) ? resolve(NOT_STAGED_CHANGES.test(v)) : reject(e))
57
+ })
58
+ )
59
+ }
60
+
61
+ export function notPushedChanges () {
62
+ log('notPushedChanges')
63
+
64
+ return (
65
+ new Promise((resolve, reject) => {
66
+ exec('git log origin/master..HEAD', OPTIONS, (e, v) => (!e) ? resolve(!!v) : reject(e))
67
+ })
68
+ )
69
+ }
70
+
71
+ export function patchPackageVersion () {
72
+ log('patchPackageVersion')
73
+
74
+ return (
75
+ new Promise((resolve, reject) => {
76
+ exec('npm version patch -m %s -n --no-git-tag-version --no-verify', OPTIONS, (e) => (!e) ? resolve() : reject(e))
77
+ })
78
+ )
79
+ }
80
+
81
+ export function addPackageVersionChanges () {
82
+ log('addPackageVersionChanges')
83
+
84
+ return (
85
+ new Promise((resolve, reject) => {
86
+ exec('git add package.json package-lock.json', OPTIONS, (e) => (!e) ? resolve() : reject(e))
87
+ })
88
+ )
89
+ }
90
+
91
+ export default async function preCommit () {
92
+ log('pre-commit')
93
+
94
+ try {
95
+ /**
96
+ * Not changes added, exit
97
+ */
98
+ if (await notStagedChanges()) return
99
+ /**
100
+ * Has changes added, continue
101
+ */
102
+ if (await hasStagedChanges()) {
103
+ /**
104
+ * Not package version changes, continue
105
+ */
106
+ if (await notPackageVersionChanges()) {
107
+ await patchPackageVersion()
108
+ await addPackageVersionChanges()
109
+ }
110
+ }
111
+ } catch ({ code = 'NONE', message = 'No error message defined' }) {
112
+ log({ code, message })
113
+ }
114
+ }
package/gulpfile.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import gulp from 'gulp'
2
+
3
+ import preCommit from '#build/gulp/pre-commit'
4
+
5
+ gulp
6
+ .task('pre-commit', preCommit)
7
+
8
+ gulp
9
+ .task('default', gulp.series('pre-commit'))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequencemedia/minimserver",
3
- "version": "0.1.27",
3
+ "version": "1.2.2",
4
4
  "description": "Watch for changes to M3Us and rescan MinimServer",
5
5
  "keywords": [
6
6
  "minimserver",
@@ -14,7 +14,7 @@
14
14
  "m3u",
15
15
  "m3u8"
16
16
  ],
17
- "main": "./app.js",
17
+ "main": "./app.mjs",
18
18
  "author": "Jonathan Perry for Sequence Media Limited <sequencemedia@sequencemedia.net>",
19
19
  "license": "MIT",
20
20
  "engines": {
@@ -29,49 +29,42 @@
29
29
  "url": "https://github.com/sequencemedia/minimserver/issues"
30
30
  },
31
31
  "scripts": {
32
- "build": "npm run babel",
33
- "build:watch": "npm run babel:watch",
34
- "clean": "rimraf lib",
35
- "babel": "babel src -d lib",
36
- "babel:watch": "npm run babel -- -w",
37
- "lint": "eslint .",
32
+ "lint": "eslint . --ext .mjs --ext .cjs",
38
33
  "lint:fix": "npm run lint -- --fix",
39
- "start": "cross-env DEBUG=minimserver*,itunes* NODE_ENV=production node app",
40
- "start:dev": "cross-env DEBUG=minimserver*,itunes* NODE_ENV=development node app",
41
- "prepublishOnly": "npm run build",
42
- "prebuild": "npm run clean"
34
+ "start": "cross-env DEBUG=@sequencemedia/minimserver* NODE_ENV=production node .",
35
+ "dev": "cross-env DEBUG=@sequencemedia/minimserver* NODE_ENV=development node .",
36
+ "gulp": "gulp --color",
37
+ "pre-commit": "npm run lint && cross-env DEBUG=@sequencemedia/minimserver,@sequencemedia/minimserver:* npm run gulp -- pre-commit",
38
+ "prepare": "husky install"
43
39
  },
44
40
  "dependencies": {
45
- "@babel/runtime": "^7.16.3",
46
41
  "anymatch": "^3.1.2",
47
42
  "chokidar": "^3.5.2",
48
43
  "commander": "^8.3.0",
49
44
  "cross-env": "^7.0.3",
50
- "debug": "^4.3.2",
45
+ "debug": "^4.3.3",
51
46
  "del": "^6.0.0",
52
47
  "dotenv": "^10.0.0",
53
48
  "fs-extra": "^10.0.0",
54
- "ps-list": "7.2.0",
55
- "supports-color": "^9.1.0"
49
+ "ps-list": "^8.0.0",
50
+ "supports-color": "^9.2.1"
56
51
  },
57
52
  "devDependencies": {
58
53
  "@babel/cli": "^7.16.0",
59
- "@babel/core": "^7.16.0",
60
- "@babel/eslint-parser": "^7.16.3",
61
- "@babel/plugin-proposal-export-default-from": "^7.16.0",
62
- "@babel/plugin-proposal-export-namespace-from": "^7.16.0",
63
- "@babel/plugin-transform-runtime": "^7.16.4",
64
- "@babel/preset-env": "^7.16.4",
65
- "@babel/register": "^7.16.0",
66
- "babel-plugin-module-resolver": "^4.1.0",
67
- "babel-plugin-syntax-async-functions": "^6.13.0",
68
- "core-js": "^3.19.1",
54
+ "@babel/core": "^7.16.5",
55
+ "@babel/eslint-parser": "^7.16.5",
56
+ "@babel/preset-env": "^7.16.5",
57
+ "core-js": "^3.20.1",
69
58
  "eslint": "7.32.0",
70
59
  "eslint-config-standard": "^16.0.3",
71
- "eslint-import-resolver-babel-module": "^5.3.1",
72
60
  "eslint-plugin-import": "^2.25.3",
73
61
  "eslint-plugin-node": "^11.1.0",
74
- "eslint-plugin-promise": "^5.1.1",
75
- "rimraf": "^3.0.2"
62
+ "eslint-plugin-promise": "5.2.0",
63
+ "gulp": "^4.0.2",
64
+ "husky": "^7.0.4"
65
+ },
66
+ "imports": {
67
+ "#minimserver": "./src/index.mjs",
68
+ "#build/gulp/*": "./build/gulp/*.mjs"
76
69
  }
77
70
  }
@@ -1,13 +1,12 @@
1
+ import debug from 'debug'
2
+
1
3
  import os from 'os'
2
4
  import path from 'path'
3
5
  import {
4
6
  exec
5
7
  } from 'child_process'
6
8
 
7
- import {
8
- ensureDir,
9
- ensureFile
10
- } from 'fs-extra'
9
+ import fsExtra from 'fs-extra'
11
10
 
12
11
  import {
13
12
  stat,
@@ -18,10 +17,13 @@ import chokidar from 'chokidar'
18
17
  import anymatch from 'anymatch'
19
18
  import del from 'del'
20
19
 
21
- import debug from 'debug'
20
+ const {
21
+ ensureDir,
22
+ ensureFile
23
+ } = fsExtra
22
24
 
23
- const error = debug('minimserver:error')
24
- const log = debug('minimserver')
25
+ const error = debug('@sequencemedia/minimserver:error')
26
+ const log = debug('@sequencemedia/minimserver')
25
27
 
26
28
  log('`minimserver` is awake')
27
29
 
@@ -49,7 +51,9 @@ export async function removeAllM3UFromDestinationDir (path) {
49
51
  /**
50
52
  * log('removeAllM3UFromDestinationDir')
51
53
  */
52
- return await del(path, { force: true })
54
+ return (
55
+ await del(path, { force: true })
56
+ )
53
57
  }
54
58
 
55
59
  export function ensureDestinationDir (path) {
@@ -192,7 +196,9 @@ export function removeFactory (origin, destination) {
192
196
  log('remove', to)
193
197
 
194
198
  try {
195
- return await del(to, { force: true })
199
+ return (
200
+ await del(to, { force: true })
201
+ )
196
202
  } catch ({ message }) {
197
203
  error(message)
198
204
  }
@@ -345,7 +351,7 @@ export function ignorePatternFactory (ignore) {
345
351
  }
346
352
  }
347
353
 
348
- export async function execute (
354
+ export default async function minimServer (
349
355
  origin = '.',
350
356
  destination = '.',
351
357
  server = 'http://0.0.0.0:9790',
@@ -353,7 +359,7 @@ export async function execute (
353
359
  bounce = 60000
354
360
  ) {
355
361
  /*
356
- * log('execute')
362
+ * log('minimServer')
357
363
  */
358
364
  let watcher
359
365
 
package/babel.config.js DELETED
@@ -1,35 +0,0 @@
1
- const presets = [
2
- [
3
- '@babel/env',
4
- {
5
- useBuiltIns: 'usage',
6
- targets: {
7
- node: 'current'
8
- },
9
- corejs: 3
10
- }
11
- ]
12
- ]
13
-
14
- const plugins = [
15
- '@babel/transform-runtime',
16
- '@babel/proposal-export-default-from',
17
- '@babel/proposal-export-namespace-from',
18
- 'syntax-async-functions',
19
- [
20
- 'module-resolver', {
21
- root: ['./src'],
22
- cwd: 'babelrc',
23
- alias: {
24
- '~': './src'
25
- }
26
- }
27
- ]
28
- ]
29
-
30
- module.exports = {
31
- compact: true,
32
- comments: false,
33
- presets,
34
- plugins
35
- }
package/lib/index.js DELETED
@@ -1 +0,0 @@
1
- "use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.changeFactory=changeFactory;exports.createFactory=createFactory;exports.ensureDestinationDir=ensureDestinationDir;exports.ensureDestinationM3U=ensureDestinationM3U;exports.execute=execute;exports.exit=exit;exports.ignorePatternFactory=ignorePatternFactory;exports.queueRelaunchFactory=queueRelaunchFactory;exports.queueRescanFactory=queueRescanFactory;exports.queueRestartFactory=queueRestartFactory;exports.relaunch=relaunch;exports.removeAllM3UFromDestinationDir=removeAllM3UFromDestinationDir;exports.removeFactory=removeFactory;exports.rescan=rescan;exports.restart=restart;var _os=_interopRequireDefault(require("os"));var _path=_interopRequireDefault(require("path"));var _child_process=require("child_process");var _fsExtra=require("fs-extra");var _promises=require("fs/promises");var _chokidar=_interopRequireDefault(require("chokidar"));var _anymatch=_interopRequireDefault(require("anymatch"));var _del=_interopRequireDefault(require("del"));var _debug=_interopRequireDefault(require("debug"));const error=(0,_debug.default)('minimserver:error');const log=(0,_debug.default)('minimserver');log('`minimserver` is awake');async function originDirExists(path){try{await(0,_promises.stat)(path);return true;}catch(e){const{code}=e;if(code!=='ENOENT'){const{message}=e;error(message);}return false;}}async function removeAllM3UFromDestinationDir(path){return await(0,_del.default)(path,{force:true});}function ensureDestinationDir(path){return new Promise((resolve,reject)=>{(0,_fsExtra.ensureDir)(path,e=>!e?resolve():reject(e));});}function ensureDestinationM3U(filePath){return new Promise((resolve,reject)=>{(0,_fsExtra.ensureFile)(filePath,e=>!e?resolve():reject(e));});}function rescan(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d rescan`,(e,r)=>!e?resolve(r):reject(e));});}function restart(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d restart`,(e,r)=>!e?resolve(r):reject(e));});}function relaunch(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d relaunch`,(e,r)=>!e?resolve(r):reject(e));});}function exit(server){return new Promise((resolve,reject)=>{(0,_child_process.exec)(`curl -X POST -H "Content-Type: text/plain" ${server} -d exit`,(e,r)=>!e?resolve(r):reject(e));});}function createFactory(origin,destination){return async function create(filePath){const to=filePath.replace(origin,destination);log('create',to);try{await ensureDestinationM3U(to);return await(0,_promises.copyFile)(filePath,to);}catch(e){const{code}=e;if(code==='ENOENT'){error(`ENOENT in create for "${filePath}"`);}else{const{message}=e;error(message);}}};}function changeFactory(origin,destination){return async function change(filePath){const to=filePath.replace(origin,destination);log('change',to);try{await ensureDestinationM3U(to);return await(0,_promises.copyFile)(filePath,to);}catch(e){const{code}=e;if(code==='ENOENT'){error(`ENOENT in change for "${filePath}"`);}else{const{message}=e;error(message);}}};}function removeFactory(origin,destination){return async function remove(filePath){const to=filePath.replace(origin,destination);log('remove',to);try{return await(0,_del.default)(to,{force:true});}catch({message}){error(message);}};}function queueRescanFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await rescan(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function queueRestartFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await restart(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function queueRelaunchFactory(server,bounce){let t=null;let x=null;let y=null;return function enqueue(){if(t){clearTimeout(t);if(x){y=true;return;}}t=setTimeout(async function dequeue(){x=true;try{const response=await relaunch(server);log(response.trim());t=null;x=null;if(y){y=null;enqueue();}}catch({message}){error(message);}},bounce);};}function ignorePatternFactory(ignore){const ignorePatterns=ignore.split(',');return function ignorePattern(filePath){return /(^|[/\\])\../.test(filePath)||(0,_anymatch.default)(ignorePatterns,filePath);};}async function execute(origin='.',destination='.',server='http://0.0.0.0:9790',ignore='',bounce=60000){let watcher;try{const o=_path.default.resolve(origin.replace('~',_os.default.homedir));if(!(await originDirExists(o)))throw new Error(`Origin "${origin}" does not exist.`);const d=_path.default.resolve(destination.replace('~',_os.default.homedir));const ignorePattern=ignorePatternFactory(ignore);watcher=_chokidar.default.watch(o,{ignored:ignorePattern});const create=createFactory(o,d);const change=changeFactory(o,d);const remove=removeFactory(o,d);await ensureDestinationDir(d);await removeAllM3UFromDestinationDir(d);const queueRescan=queueRescanFactory(server,bounce);watcher.on('add',async function handleAdd(filePath){try{await create(filePath);queueRescan();}catch({message}){error(message);}}).on('change',async function handleChange(filePath){try{await change(filePath);queueRescan();}catch({message}){error(message);}}).on('unlink',async function handleUnlink(filePath){try{await remove(filePath);queueRescan();}catch({message}){error(message);}}).on('error',function handleError({message}){error(`Error in watcher: "${message}"`);});queueRescan();}catch({message}){if(watcher)watcher.close();error(message);}}