ol-stac 0.0.0 → 0.0.1

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.
Files changed (120) hide show
  1. package/README.md +1 -1
  2. package/events/ErrorEvent.d.ts +17 -0
  3. package/events/ErrorEvent.d.ts.map +1 -0
  4. package/{src/ol/events → events}/ErrorEvent.js +9 -11
  5. package/events/ErrorEvent.js.map +1 -0
  6. package/layer/STAC.d.ts +422 -0
  7. package/layer/STAC.d.ts.map +1 -0
  8. package/layer/STAC.js +698 -0
  9. package/layer/STAC.js.map +1 -0
  10. package/layer/stacUtil.d.ts +46 -0
  11. package/layer/stacUtil.d.ts.map +1 -0
  12. package/layer/stacUtil.js +154 -0
  13. package/layer/stacUtil.js.map +1 -0
  14. package/package.json +3 -85
  15. package/source/GeoTIFF2.d.ts +35 -0
  16. package/source/GeoTIFF2.d.ts.map +1 -0
  17. package/{src/ol/source → source}/GeoTIFF2.js +9 -16
  18. package/source/GeoTIFF2.js.map +1 -0
  19. package/.eslintignore +0 -2
  20. package/.github/workflows/deploy.yml +0 -67
  21. package/.github/workflows/publish.yml +0 -32
  22. package/.github/workflows/release.yml +0 -21
  23. package/.github/workflows/test.yml +0 -85
  24. package/CHANGELOG.md +0 -14
  25. package/DEVELOPING.md +0 -104
  26. package/config/jsdoc/api/conf.json +0 -38
  27. package/config/jsdoc/api/index.md +0 -1
  28. package/config/jsdoc/api/readme.md +0 -65
  29. package/config/jsdoc/api/template/README.md +0 -3
  30. package/config/jsdoc/api/template/publish.js +0 -743
  31. package/config/jsdoc/api/template/static/scripts/linenumber.js +0 -11
  32. package/config/jsdoc/api/template/static/scripts/main.js +0 -305
  33. package/config/jsdoc/api/template/static/scripts/prettify/Apache-License-2.0.txt +0 -202
  34. package/config/jsdoc/api/template/static/scripts/prettify/lang-css.js +0 -2
  35. package/config/jsdoc/api/template/static/scripts/prettify/prettify.js +0 -28
  36. package/config/jsdoc/api/template/static/styles/carbon.css +0 -65
  37. package/config/jsdoc/api/template/static/styles/jaguar.css +0 -512
  38. package/config/jsdoc/api/template/static/styles/prettify-jsdoc.css +0 -111
  39. package/config/jsdoc/api/template/static/styles/prettify-tomorrow.css +0 -132
  40. package/config/jsdoc/api/template/static/theme +0 -1
  41. package/config/jsdoc/api/template/tmpl/container.tmpl +0 -205
  42. package/config/jsdoc/api/template/tmpl/details.tmpl +0 -84
  43. package/config/jsdoc/api/template/tmpl/example.tmpl +0 -2
  44. package/config/jsdoc/api/template/tmpl/examples.tmpl +0 -16
  45. package/config/jsdoc/api/template/tmpl/exceptions.tmpl +0 -30
  46. package/config/jsdoc/api/template/tmpl/layout.tmpl +0 -92
  47. package/config/jsdoc/api/template/tmpl/mainpage.tmpl +0 -14
  48. package/config/jsdoc/api/template/tmpl/members.tmpl +0 -38
  49. package/config/jsdoc/api/template/tmpl/method.tmpl +0 -132
  50. package/config/jsdoc/api/template/tmpl/navigation.tmpl +0 -59
  51. package/config/jsdoc/api/template/tmpl/observables.tmpl +0 -39
  52. package/config/jsdoc/api/template/tmpl/params.tmpl +0 -109
  53. package/config/jsdoc/api/template/tmpl/properties.tmpl +0 -85
  54. package/config/jsdoc/api/template/tmpl/returns.tmpl +0 -72
  55. package/config/jsdoc/api/template/tmpl/source.tmpl +0 -8
  56. package/config/jsdoc/api/template/tmpl/stability.tmpl +0 -7
  57. package/config/jsdoc/api/template/tmpl/tutorial.tmpl +0 -19
  58. package/config/jsdoc/api/template/tmpl/type.tmpl +0 -7
  59. package/config/jsdoc/info/conf.json +0 -22
  60. package/config/jsdoc/info/publish.js +0 -175
  61. package/config/jsdoc/package.json +0 -4
  62. package/config/jsdoc/plugins/api.cjs +0 -181
  63. package/config/jsdoc/plugins/default-export.cjs +0 -35
  64. package/config/jsdoc/plugins/define-plugin.cjs +0 -33
  65. package/config/jsdoc/plugins/events.cjs +0 -39
  66. package/config/jsdoc/plugins/inline-options.cjs +0 -102
  67. package/config/jsdoc/plugins/markdown.cjs +0 -119
  68. package/config/jsdoc/plugins/observable.cjs +0 -69
  69. package/config/jsdoc/plugins/virtual-plugin.cjs +0 -16
  70. package/config/rollup-full-build.js +0 -24
  71. package/config/tsconfig-build.json +0 -25
  72. package/examples/.eslintrc +0 -29
  73. package/examples/index.html +0 -100
  74. package/examples/index.js +0 -109
  75. package/examples/planetary-computer.html +0 -14
  76. package/examples/planetary-computer.js +0 -53
  77. package/examples/resources/Jugl.js +0 -15
  78. package/examples/resources/common.js +0 -111
  79. package/examples/stac-collection-webmaplinks.html +0 -9
  80. package/examples/stac-collection-webmaplinks.js +0 -55
  81. package/examples/stac-item-from-object.html +0 -9
  82. package/examples/stac-item-from-object.js +0 -102
  83. package/examples/stac-item-tileserver.html +0 -9
  84. package/examples/stac-item-tileserver.js +0 -34
  85. package/examples/stac-item.html +0 -9
  86. package/examples/stac-item.js +0 -45
  87. package/examples/stac-itemcollection.html +0 -11
  88. package/examples/stac-itemcollection.js +0 -39
  89. package/examples/templates/example.html +0 -206
  90. package/examples/templates/readme.md +0 -3
  91. package/examples/webpack/config.mjs +0 -69
  92. package/examples/webpack/example-builder.js +0 -410
  93. package/site/build.js +0 -26
  94. package/site/layouts/default.hbs +0 -78
  95. package/site/src/doc/faq.md +0 -8
  96. package/site/src/doc/index.md +0 -22
  97. package/site/src/doc/quickstart.md +0 -121
  98. package/site/src/doc/tutorials/index.md +0 -8
  99. package/site/src/download/index.hbs +0 -62
  100. package/site/src/favicon.ico +0 -0
  101. package/site/src/index.hbs +0 -71
  102. package/site/src/theme/index.css +0 -26
  103. package/site/src/theme/site.css +0 -531
  104. package/src/ol/layer/STAC.js +0 -780
  105. package/src/ol/layer/stacUtil.js +0 -169
  106. package/tasks/.eslintrc +0 -5
  107. package/tasks/build-website.sh +0 -90
  108. package/tasks/create-release.js +0 -107
  109. package/tasks/generate-index.js +0 -125
  110. package/tasks/generate-info.js +0 -189
  111. package/tasks/get-latest-release.js +0 -36
  112. package/tasks/newest-tag.js +0 -52
  113. package/tasks/prepare-package.js +0 -46
  114. package/tasks/publish.sh +0 -90
  115. package/test/README.md +0 -56
  116. package/test/browser/.eslintrc +0 -14
  117. package/test/browser/karma.config.cjs +0 -94
  118. package/test/browser/spec/ol/layer/STAC.test.js +0 -18
  119. package/test/browser/test-extensions.js +0 -419
  120. package/tsconfig.json +0 -62
@@ -1,169 +0,0 @@
1
- import VectorLayer from 'ol/layer/Vector.js';
2
- import {Fill, Stroke, Style} from 'ol/style.js';
3
- import {STAC} from 'stac-js';
4
- import {WMTSCapabilities} from 'ol/format.js';
5
- import {
6
- fromEPSGCode,
7
- isRegistered as isProj4Registered,
8
- } from 'ol/proj/proj4.js';
9
-
10
- export const defaultBoundsStyle = new Style({
11
- fill: new Fill({
12
- color: 'rgba(255,255,255,0.4)',
13
- }),
14
- stroke: new Stroke({
15
- color: '#3399CC',
16
- width: 3,
17
- }),
18
- });
19
-
20
- export const defaultCollectionStyle = new Style({
21
- stroke: new Stroke({
22
- color: '#ff9933',
23
- width: 1,
24
- }),
25
- });
26
-
27
- /**
28
- * Get the STAC objects associated with this event, if any. Excludes API Collections.
29
- * @param {import('ol/MapBrowserEvent.js').default} event The asset to read the information from.
30
- * @return {Promise<Array<STAC>>} A list of STAC objects
31
- */
32
- export async function getStacObjectsForEvent(event) {
33
- const objects = event.map
34
- .getAllLayers()
35
- .filter((layer) => {
36
- if (
37
- layer instanceof VectorLayer &&
38
- layer.get('bounds') === true &&
39
- layer.get('stac') instanceof STAC
40
- ) {
41
- const features = layer
42
- .getSource()
43
- .getFeaturesAtCoordinate(event.coordinate);
44
- return features.length > 0;
45
- }
46
- return false;
47
- })
48
- .map((layer) => layer.get('stac'));
49
- // Make sure we return no duplicates
50
- return [...new Set(objects)];
51
- }
52
-
53
- /**
54
- * Get the source info for the GeoTiff from the asset.
55
- * @param {import('stac-js').Asset} asset The asset to read the information from.
56
- * @param {Array<number>} bands The (one-based) bands to show.
57
- * @return {import('ol/source/GeoTIFF.js').SourceInfo} The source info for the GeoTiff asset
58
- */
59
- export function getGeoTiffSourceInfoFromAsset(asset, bands) {
60
- const sourceInfo = {
61
- url: asset.getAbsoluteUrl(),
62
- };
63
-
64
- let band = null;
65
- // If there's just one band, we can also read the information from there.
66
- if (asset.getBands().length === 1) {
67
- band = 0;
68
- }
69
-
70
- // TODO: It would be useful if OL would allow min/max values per band
71
- const {minimum, maximum} = asset.getMinMaxValues(band);
72
- if (typeof minimum === 'number') {
73
- sourceInfo.min = minimum;
74
- }
75
- if (typeof maximum === 'number') {
76
- sourceInfo.max = maximum;
77
- }
78
-
79
- // TODO: It would be useful if OL would allow multiple no-data values
80
- const nodata = asset.getNoDataValues(band);
81
- if (nodata.length > 0) {
82
- sourceInfo.nodata = nodata[0];
83
- } else {
84
- sourceInfo.nodata = NaN; // NaN is usually a reasonable default if nothing is provided
85
- }
86
-
87
- if (bands.length > 0) {
88
- sourceInfo.bands = bands;
89
- }
90
-
91
- return sourceInfo;
92
- }
93
-
94
- /**
95
- * Gets the projection from the asset or link.
96
- * @param {import('stac-js').STACReference} reference The asset or link to read the information from.
97
- * @param {import('ol/proj.js').ProjectionLike} defaultProjection A default projection to use.
98
- * @return {Promise<import('ol/proj.js').ProjectionLike>} The projection, if any.
99
- */
100
- export async function getProjection(reference, defaultProjection = undefined) {
101
- let projection = defaultProjection;
102
- if (isProj4Registered()) {
103
- // TODO: It would be great to handle WKT2 and PROJJSON, but is not supported yet by proj4js.
104
- const epsgCode = reference.getMetadata('proj:epsg');
105
- if (epsgCode) {
106
- try {
107
- projection = await fromEPSGCode(epsgCode);
108
- } catch (_) {
109
- // pass
110
- }
111
- }
112
- }
113
- return projection;
114
- }
115
-
116
- /**
117
- * Returns the style for the footprint.
118
- * Removes the fill if anything is meant to be shown in the bounds.
119
- *
120
- * @param {Style} [originalStyle] The original style for the footprint.
121
- * @param {import('./STAC.js').default} [layerGroup] The associated STAC layergroup to check.
122
- * @return {Style} The adapted style for the footprint.
123
- */
124
- export function getBoundsStyle(originalStyle, layerGroup) {
125
- const style = originalStyle.clone();
126
- if (!layerGroup.hasOnlyBounds()) {
127
- style.setFill(null);
128
- }
129
- return style;
130
- }
131
-
132
- /**
133
- * Get a URL from a web-map-link that is specific enough, i.e.
134
- * replaces any occurances of {s} if possible, otherwise returns null.
135
- * @param {import('./STAC.js').Link} link The web map link.
136
- * @return {string|null} Specific URL
137
- */
138
- export function getSpecificWebMapUrl(link) {
139
- let url = link.href;
140
- if (url.includes('{s}')) {
141
- if (
142
- Array.isArray(link['href:servers']) &&
143
- link['href:servers'].length > 0
144
- ) {
145
- const i = (Math.random() * link['href:servers'].length) | 0;
146
- url = url.replace('{s}', link['href:servers'][i]);
147
- } else {
148
- return null;
149
- }
150
- }
151
- return url;
152
- }
153
-
154
- /**
155
- * Gets the WMTS capabilities from the given web-map-links URL.
156
- * @param {string} url Base URL for the WMTS
157
- * @return {Promise<Object|null>} Resolves with the WMTS Capabilities object
158
- */
159
- export async function getWmtsCapabilities(url) {
160
- try {
161
- const urlObj = new URL(url);
162
- urlObj.searchParams.set('service', 'wmts');
163
- urlObj.searchParams.set('request', 'GetCapabilities');
164
- const response = await fetch(urlObj);
165
- return new WMTSCapabilities().read(await response.text());
166
- } catch (error) {
167
- return null;
168
- }
169
- }
package/tasks/.eslintrc DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "env": {
3
- "node": true
4
- }
5
- }
@@ -1,90 +0,0 @@
1
- #!/bin/bash
2
-
3
- #
4
- # Run this script to build the website.
5
- #
6
- set -o errexit
7
-
8
- #
9
- # Destination directory for the website.
10
- #
11
- build=build/site
12
-
13
- usage() {
14
- cat <<-EOF
15
-
16
- Usage: ${1} [options]
17
-
18
- Options:
19
- -v <version>
20
- Version identifier. If omitted, the current branch name will be used.
21
-
22
- -l <version>
23
- The latest release version. If provided, the root of the website will be
24
- rebuilt using this version identifier. If the -l value matches the -v value,
25
- the examples and API docs will be copied to en/latest. If the -l option
26
- is omitted, only the examples and API docs will be rebuilt (not the root of the site).
27
- EOF
28
- exit 1;
29
- }
30
-
31
- root=false
32
-
33
- while getopts ":v:l:" o; do
34
- case "${o}" in
35
- v)
36
- version=${OPTARG}
37
- ;;
38
- l)
39
- latest=${OPTARG}
40
- ;;
41
- *)
42
- usage
43
- ;;
44
- esac
45
- done
46
- shift $((OPTIND-1))
47
-
48
- if [ -z "${version}" ]; then
49
- version=$(git branch --show-current)
50
- fi
51
-
52
- root=$(cd -P -- "$(dirname -- "${0}")" && pwd -P)/..
53
- cd ${root}
54
-
55
- rm -rf ${build}
56
-
57
- if [ -n "${latest}" ] ; then
58
- echo "Building the website root with ${latest}"
59
- mkdir -p ${build}
60
- OL_VERSION=${latest} node site/build.js
61
- cp -r site/build/* ${build}/
62
- fi
63
-
64
- mkdir -p ${build}/en/${version}/
65
-
66
- echo "Building examples for ${version}"
67
- npm run build-examples
68
- mv build/examples ${build}/en/${version}/
69
-
70
- echo "Building API docs for ${version}"
71
- npm run apidoc
72
- mv build/apidoc ${build}/en/${version}/
73
-
74
- echo "Building the package ${version}"
75
- npm run build-package
76
- mv build/ol ${build}/en/${version}/
77
-
78
- if [[ "${latest}" == "${version}" ]] ; then
79
- echo "Copying to en/latest"
80
- cp -r ${build}/en/${version} ${build}/en/latest
81
-
82
- echo "Building release artifacts"
83
- pushd ${build}
84
- zip -r ${OLDPWD}/build/${version}-site.zip . -x "en/${version}/*"
85
- popd
86
-
87
- pushd ${build}/en/${version}/ol
88
- zip -r ${OLDPWD}/build/${version}-package.zip .
89
- popd
90
- fi
@@ -1,107 +0,0 @@
1
- import esMain from 'es-main';
2
- import yargs from 'yargs';
3
- import {Octokit} from '@octokit/rest';
4
- import {basename} from 'node:path';
5
- import {hideBin} from 'yargs/helpers';
6
- import {readFile, stat} from 'node:fs/promises';
7
-
8
- /**
9
- * @typedef {Object} Options
10
- * @property {string} token The bearer token.
11
- * @property {string} tag The tag.
12
- * @property {boolean} draft Create a draft release.
13
- * @property {boolean} notes Generate release notes.
14
- * @property {string} site Path to zip archive with site contents.
15
- * @property {string} package Path to zip archive with source and full build.
16
- */
17
-
18
- const owner = 'm-mohr';
19
- const repo = 'ol-stac';
20
-
21
- /**
22
- * Create a release.
23
- * @param {Options} options The release options.
24
- */
25
- async function createRelease(options) {
26
- const client = new Octokit({
27
- auth: options.token,
28
- });
29
-
30
- const response = await client.rest.repos.createRelease({
31
- owner,
32
- repo,
33
- tag_name: options.tag,
34
- generate_release_notes: options.notes,
35
- draft: options.draft,
36
- });
37
-
38
- await uploadAsset(
39
- client,
40
- response.data,
41
- options.site,
42
- 'Examples and docs (zip)'
43
- );
44
-
45
- await uploadAsset(
46
- client,
47
- response.data,
48
- options.package,
49
- 'Package archive (zip)'
50
- );
51
- }
52
-
53
- async function uploadAsset(client, release, assetPath, label) {
54
- const name = basename(assetPath);
55
- const stats = await stat(assetPath);
56
- const data = await readFile(assetPath);
57
-
58
- await client.rest.repos.uploadReleaseAsset({
59
- url: release.upload_url,
60
- name,
61
- label,
62
- headers: {
63
- 'content-type': 'application/zip',
64
- 'content-length': stats.size,
65
- },
66
- data,
67
- });
68
- }
69
-
70
- if (esMain(import.meta)) {
71
- const options = yargs(hideBin(process.argv))
72
- .option('token', {
73
- describe: 'The token for auth',
74
- type: 'string',
75
- })
76
- .demandOption('token')
77
- .option('tag', {
78
- describe: 'The release tag (e.g. v7.0.0)',
79
- type: 'string',
80
- })
81
- .demandOption('tag')
82
- .option('package', {
83
- describe: 'Path to the archive with the source package',
84
- type: 'string',
85
- })
86
- .demandOption('package')
87
- .option('site', {
88
- describe: 'Path to the archive with the site contents',
89
- type: 'string',
90
- })
91
- .demandOption('site')
92
- .option('draft', {
93
- describe: 'Create a draft release',
94
- type: 'boolean',
95
- default: true,
96
- })
97
- .option('notes', {
98
- describe: 'Generate release notes',
99
- type: 'boolean',
100
- default: true,
101
- })
102
- .parse();
103
-
104
- createRelease(options).catch((err) => {
105
- process.stderr.write(`${err.stack}\n`, () => process.exit(1));
106
- });
107
- }
@@ -1,125 +0,0 @@
1
- import esMain from 'es-main';
2
- import fse from 'fs-extra';
3
- import generateInfo from './generate-info.js';
4
- import path, {dirname} from 'path';
5
- import {fileURLToPath} from 'url';
6
-
7
- /**
8
- * Read the symbols from info file.
9
- * @return {Promise<Array>} Resolves with an array of symbol objects.
10
- */
11
- async function getSymbols() {
12
- const info = await generateInfo();
13
- return info.symbols.filter((symbol) => symbol.kind != 'member');
14
- }
15
-
16
- /**
17
- * Generate an import statement.
18
- * @param {Object} symbol Symbol.
19
- * @param {string} member Member.
20
- * @return {string} An import statement.
21
- */
22
- function getImport(symbol, member) {
23
- const defaultExport = symbol.name.split('~');
24
- if (symbol.isDefaultExport) {
25
- const from = defaultExport[0].replace(/^module\:/, './');
26
- const importName = from.replace(/[.\/]+/g, '$');
27
- return `import ${importName} from '${from}.js';`;
28
- }
29
- const namedExport = symbol.name.split('.');
30
- if (
31
- member &&
32
- namedExport.length > 1 &&
33
- (defaultExport.length <= 1 || defaultExport[0].includes('.'))
34
- ) {
35
- const from = namedExport[0].replace(/^module\:/, './');
36
- const importName = from.replace(/[.\/]+/g, '_');
37
- return `import {${member} as ${importName}$${member}} from '${from}.js';`;
38
- }
39
- return '';
40
- }
41
-
42
- /**
43
- * Generate code to export a named symbol.
44
- * @param {Object} symbol Symbol.
45
- * @param {Object<string, string>} namespaces Already defined namespaces.
46
- * @param {Object} imports Imports.
47
- * @return {string} Export code.
48
- */
49
- function formatSymbolExport(symbol, namespaces, imports) {
50
- const name = symbol.name;
51
- const parts = name.split('~');
52
- const nsParts = parts[0].replace(/^module\:/, '').split(/[\/\.]/);
53
- const last = nsParts.length - 1;
54
- const imp = getImport(symbol, nsParts[last]);
55
- if (imp) {
56
- const isNamed = parts[0].includes('.');
57
- const importName = isNamed
58
- ? '_' + nsParts.slice(0, last).join('_') + '$' + nsParts[last]
59
- : '$' + nsParts.join('$');
60
- let line = nsParts[0];
61
- for (let i = 1, ii = nsParts.length; i < ii; ++i) {
62
- line += `.${nsParts[i]}`;
63
- namespaces[line] =
64
- (line in namespaces ? namespaces[line] : true) && i < ii - 1;
65
- }
66
- line += ` = ${importName};`;
67
- imports[imp] = true;
68
- return line;
69
- }
70
- return '';
71
- }
72
-
73
- /**
74
- * Generate export code given a list symbol names.
75
- * @param {Array<Object>} symbols List of symbols.
76
- * @return {string} Export code.
77
- */
78
- function generateExports(symbols) {
79
- const namespaces = {};
80
- const imports = {};
81
- const blocks = [];
82
- symbols.forEach(function (symbol) {
83
- const name = symbol.name;
84
- if (!name.includes('#')) {
85
- const imp = getImport(symbol);
86
- if (imp) {
87
- imports[imp] = true;
88
- }
89
- const line = formatSymbolExport(symbol, namespaces, imports);
90
- if (line) {
91
- blocks.push(line);
92
- }
93
- }
94
- });
95
- const defs = [...new Set(blocks)];
96
- const lines = Object.keys(imports).concat(defs.sort());
97
- lines.push('', 'export default ol;');
98
- return lines.join('\n');
99
- }
100
-
101
- /**
102
- * Generate the exports code.
103
- * @return {Promise<string>} Resolves with the exports code.
104
- */
105
- export default async function main() {
106
- const symbols = await getSymbols();
107
- return generateExports(symbols);
108
- }
109
-
110
- /**
111
- * If running this module directly, read the config file, call the main
112
- * function, and write the output file.
113
- */
114
- if (esMain(import.meta)) {
115
- const baseDir = dirname(fileURLToPath(import.meta.url));
116
-
117
- main()
118
- .then(async (code) => {
119
- const filepath = path.join(baseDir, '..', 'build', 'index.js');
120
- await fse.outputFile(filepath, code);
121
- })
122
- .catch((err) => {
123
- process.stderr.write(`${err.message}\n`, () => process.exit(1));
124
- });
125
- }
@@ -1,189 +0,0 @@
1
- import esMain from 'es-main';
2
- import fse from 'fs-extra';
3
- import path, {dirname} from 'path';
4
- import {fileURLToPath} from 'url';
5
- import {spawn} from 'child_process';
6
- import {walk} from 'walk';
7
-
8
- const isWindows = process.platform.startsWith('win');
9
- const baseDir = dirname(fileURLToPath(import.meta.url));
10
-
11
- const sourceDir = path.join(baseDir, '..', 'src');
12
- const infoPath = path.join(baseDir, '..', 'build', 'info.json');
13
-
14
- /**
15
- * Get checked path of a binary.
16
- * @param {string} binaryName Binary name of the binary path to find.
17
- * @return {string} Path.
18
- */
19
- function getBinaryPath(binaryName) {
20
- if (isWindows) {
21
- binaryName += '.cmd';
22
- }
23
-
24
- const jsdocResolved = path.join(
25
- baseDir,
26
- '..',
27
- 'node_modules',
28
- 'jsdoc',
29
- 'jsdoc.js'
30
- );
31
- const expectedPaths = [
32
- path.join(baseDir, '..', 'node_modules', '.bin', binaryName),
33
- path.resolve(
34
- path.join(path.dirname(jsdocResolved), '..', '.bin', binaryName)
35
- ),
36
- ];
37
-
38
- for (let i = 0; i < expectedPaths.length; i++) {
39
- const expectedPath = expectedPaths[i];
40
- if (fse.existsSync(expectedPath)) {
41
- return expectedPath;
42
- }
43
- }
44
-
45
- throw Error(
46
- 'JsDoc binary was not found in any of the expected paths: ' + expectedPaths
47
- );
48
- }
49
-
50
- const jsdoc = getBinaryPath('jsdoc');
51
-
52
- const jsdocConfig = path.join(
53
- baseDir,
54
- '..',
55
- 'config',
56
- 'jsdoc',
57
- 'info',
58
- 'conf.json'
59
- );
60
-
61
- /**
62
- * Generate a list of all .js paths in the source directory.
63
- * @return {Promise<Array>} Resolves to an array of source paths.
64
- */
65
- function getPaths() {
66
- return new Promise((resolve, reject) => {
67
- let paths = [];
68
-
69
- const walker = walk(sourceDir);
70
- walker.on('file', (root, stats, next) => {
71
- const sourcePath = path.join(root, stats.name);
72
- if (sourcePath.endsWith('.js')) {
73
- paths.push(sourcePath);
74
- }
75
- next();
76
- });
77
- walker.on('errors', () => {
78
- reject(new Error(`Trouble walking ${sourceDir}`));
79
- });
80
-
81
- walker.on('end', () => {
82
- /**
83
- * Windows has restrictions on length of command line, so passing all the
84
- * changed paths to a task will fail if this limit is exceeded.
85
- * To get round this, if this is Windows and there are newer files, just
86
- * pass the sourceDir to the task so it can do the walking.
87
- */
88
- if (isWindows) {
89
- paths = [sourceDir];
90
- }
91
-
92
- resolve(paths);
93
- });
94
- });
95
- }
96
-
97
- /**
98
- * Parse the JSDoc output.
99
- * @param {string} output JSDoc output
100
- * @return {Object} Symbol and define info.
101
- */
102
- function parseOutput(output) {
103
- if (!output) {
104
- throw new Error('Expected JSON output');
105
- }
106
-
107
- let info;
108
- try {
109
- info = JSON.parse(String(output));
110
- } catch (err) {
111
- throw new Error('Failed to parse output as JSON: ' + output);
112
- }
113
- if (!Array.isArray(info.symbols)) {
114
- throw new Error('Expected symbols array: ' + output);
115
- }
116
- if (!Array.isArray(info.defines)) {
117
- throw new Error('Expected defines array: ' + output);
118
- }
119
-
120
- return info;
121
- }
122
-
123
- /**
124
- * Spawn JSDoc.
125
- * @param {Array<string>} paths Paths to source files.
126
- * @return {Promise<string>} Resolves with the JSDoc output (new metadata).
127
- * If provided with an empty list of paths, resolves with null.
128
- */
129
- function spawnJSDoc(paths) {
130
- return new Promise((resolve, reject) => {
131
- let output = '';
132
- let errors = '';
133
- const cwd = path.join(baseDir, '..');
134
- const child = spawn(jsdoc, ['-c', jsdocConfig].concat(paths), {cwd: cwd});
135
-
136
- child.stdout.on('data', (data) => {
137
- output += String(data);
138
- });
139
-
140
- child.stderr.on('data', (data) => {
141
- errors += String(data);
142
- });
143
-
144
- child.on('exit', (code) => {
145
- if (code) {
146
- reject(new Error(errors || 'JSDoc failed with no output'));
147
- return;
148
- }
149
-
150
- let info;
151
- try {
152
- info = parseOutput(output);
153
- } catch (err) {
154
- reject(err);
155
- return;
156
- }
157
- resolve(info);
158
- });
159
- });
160
- }
161
-
162
- /**
163
- * Writes the info.json file.
164
- * @param {Object} info The info.
165
- * @return {Promise} Resolves on completion.
166
- */
167
- async function write(info) {
168
- await fse.outputJson(infoPath, info, {spaces: 2});
169
- }
170
-
171
- /**
172
- * Generate info from the sources.
173
- * @return {Promise<Error>} Resolves with the info object.
174
- */
175
- export default async function main() {
176
- const paths = await getPaths();
177
- return await spawnJSDoc(paths);
178
- }
179
-
180
- /**
181
- * If running this module directly, generate and write out the info.json file.
182
- */
183
- if (esMain(import.meta)) {
184
- main()
185
- .then(write)
186
- .catch((err) => {
187
- process.stderr.write(`${err.message}\n`, () => process.exit(1));
188
- });
189
- }