ol-stac 0.0.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.
Files changed (107) hide show
  1. package/.eslintignore +2 -0
  2. package/.github/workflows/deploy.yml +67 -0
  3. package/.github/workflows/publish.yml +32 -0
  4. package/.github/workflows/release.yml +21 -0
  5. package/.github/workflows/test.yml +85 -0
  6. package/CHANGELOG.md +14 -0
  7. package/DEVELOPING.md +104 -0
  8. package/LICENSE.md +201 -0
  9. package/README.md +43 -0
  10. package/config/jsdoc/api/conf.json +38 -0
  11. package/config/jsdoc/api/index.md +1 -0
  12. package/config/jsdoc/api/readme.md +65 -0
  13. package/config/jsdoc/api/template/README.md +3 -0
  14. package/config/jsdoc/api/template/publish.js +743 -0
  15. package/config/jsdoc/api/template/static/scripts/linenumber.js +11 -0
  16. package/config/jsdoc/api/template/static/scripts/main.js +305 -0
  17. package/config/jsdoc/api/template/static/scripts/prettify/Apache-License-2.0.txt +202 -0
  18. package/config/jsdoc/api/template/static/scripts/prettify/lang-css.js +2 -0
  19. package/config/jsdoc/api/template/static/scripts/prettify/prettify.js +28 -0
  20. package/config/jsdoc/api/template/static/styles/carbon.css +65 -0
  21. package/config/jsdoc/api/template/static/styles/jaguar.css +512 -0
  22. package/config/jsdoc/api/template/static/styles/prettify-jsdoc.css +111 -0
  23. package/config/jsdoc/api/template/static/styles/prettify-tomorrow.css +132 -0
  24. package/config/jsdoc/api/template/static/theme +1 -0
  25. package/config/jsdoc/api/template/tmpl/container.tmpl +205 -0
  26. package/config/jsdoc/api/template/tmpl/details.tmpl +84 -0
  27. package/config/jsdoc/api/template/tmpl/example.tmpl +2 -0
  28. package/config/jsdoc/api/template/tmpl/examples.tmpl +16 -0
  29. package/config/jsdoc/api/template/tmpl/exceptions.tmpl +30 -0
  30. package/config/jsdoc/api/template/tmpl/layout.tmpl +92 -0
  31. package/config/jsdoc/api/template/tmpl/mainpage.tmpl +14 -0
  32. package/config/jsdoc/api/template/tmpl/members.tmpl +38 -0
  33. package/config/jsdoc/api/template/tmpl/method.tmpl +132 -0
  34. package/config/jsdoc/api/template/tmpl/navigation.tmpl +59 -0
  35. package/config/jsdoc/api/template/tmpl/observables.tmpl +39 -0
  36. package/config/jsdoc/api/template/tmpl/params.tmpl +109 -0
  37. package/config/jsdoc/api/template/tmpl/properties.tmpl +85 -0
  38. package/config/jsdoc/api/template/tmpl/returns.tmpl +72 -0
  39. package/config/jsdoc/api/template/tmpl/source.tmpl +8 -0
  40. package/config/jsdoc/api/template/tmpl/stability.tmpl +7 -0
  41. package/config/jsdoc/api/template/tmpl/tutorial.tmpl +19 -0
  42. package/config/jsdoc/api/template/tmpl/type.tmpl +7 -0
  43. package/config/jsdoc/info/conf.json +22 -0
  44. package/config/jsdoc/info/publish.js +175 -0
  45. package/config/jsdoc/package.json +4 -0
  46. package/config/jsdoc/plugins/api.cjs +181 -0
  47. package/config/jsdoc/plugins/default-export.cjs +35 -0
  48. package/config/jsdoc/plugins/define-plugin.cjs +33 -0
  49. package/config/jsdoc/plugins/events.cjs +39 -0
  50. package/config/jsdoc/plugins/inline-options.cjs +102 -0
  51. package/config/jsdoc/plugins/markdown.cjs +119 -0
  52. package/config/jsdoc/plugins/observable.cjs +69 -0
  53. package/config/jsdoc/plugins/virtual-plugin.cjs +16 -0
  54. package/config/rollup-full-build.js +24 -0
  55. package/config/tsconfig-build.json +25 -0
  56. package/examples/.eslintrc +29 -0
  57. package/examples/index.html +100 -0
  58. package/examples/index.js +109 -0
  59. package/examples/planetary-computer.html +14 -0
  60. package/examples/planetary-computer.js +53 -0
  61. package/examples/resources/Jugl.js +15 -0
  62. package/examples/resources/common.js +111 -0
  63. package/examples/stac-collection-webmaplinks.html +9 -0
  64. package/examples/stac-collection-webmaplinks.js +55 -0
  65. package/examples/stac-item-from-object.html +9 -0
  66. package/examples/stac-item-from-object.js +102 -0
  67. package/examples/stac-item-tileserver.html +9 -0
  68. package/examples/stac-item-tileserver.js +34 -0
  69. package/examples/stac-item.html +9 -0
  70. package/examples/stac-item.js +45 -0
  71. package/examples/stac-itemcollection.html +11 -0
  72. package/examples/stac-itemcollection.js +39 -0
  73. package/examples/templates/example.html +206 -0
  74. package/examples/templates/readme.md +3 -0
  75. package/examples/webpack/config.mjs +69 -0
  76. package/examples/webpack/example-builder.js +410 -0
  77. package/package.json +107 -0
  78. package/site/build.js +26 -0
  79. package/site/layouts/default.hbs +78 -0
  80. package/site/src/doc/faq.md +8 -0
  81. package/site/src/doc/index.md +22 -0
  82. package/site/src/doc/quickstart.md +121 -0
  83. package/site/src/doc/tutorials/index.md +8 -0
  84. package/site/src/download/index.hbs +62 -0
  85. package/site/src/favicon.ico +0 -0
  86. package/site/src/index.hbs +71 -0
  87. package/site/src/theme/index.css +26 -0
  88. package/site/src/theme/site.css +531 -0
  89. package/src/ol/events/ErrorEvent.js +25 -0
  90. package/src/ol/layer/STAC.js +780 -0
  91. package/src/ol/layer/stacUtil.js +169 -0
  92. package/src/ol/source/GeoTIFF2.js +47 -0
  93. package/tasks/.eslintrc +5 -0
  94. package/tasks/build-website.sh +90 -0
  95. package/tasks/create-release.js +107 -0
  96. package/tasks/generate-index.js +125 -0
  97. package/tasks/generate-info.js +189 -0
  98. package/tasks/get-latest-release.js +36 -0
  99. package/tasks/newest-tag.js +52 -0
  100. package/tasks/prepare-package.js +46 -0
  101. package/tasks/publish.sh +90 -0
  102. package/test/README.md +56 -0
  103. package/test/browser/.eslintrc +14 -0
  104. package/test/browser/karma.config.cjs +94 -0
  105. package/test/browser/spec/ol/layer/STAC.test.js +18 -0
  106. package/test/browser/test-extensions.js +419 -0
  107. package/tsconfig.json +62 -0
@@ -0,0 +1,175 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ /**
4
+ * @fileoverview Generates JSON output based on exportable symbols.
5
+ */
6
+ const assert = require('assert');
7
+ const path = require('path');
8
+
9
+ /**
10
+ * Publish hook for the JSDoc template. Writes to JSON stdout.
11
+ * @param {Function} data The root of the Taffy DB containing doclet records.
12
+ * @param {Object} opts Options.
13
+ * @return {Promise} A promise that resolves when writing is complete.
14
+ */
15
+ exports.publish = function (data, opts) {
16
+ function getTypes(data) {
17
+ return data.map((name) => name.replace(/^function$/, 'Function'));
18
+ }
19
+
20
+ // get all doclets that have exports
21
+ const classes = {};
22
+ const docs = data(function () {
23
+ if (this.kind == 'class') {
24
+ classes[this.longname] = this;
25
+ return true;
26
+ }
27
+ return (
28
+ !['file', 'event', 'module'].includes(this.kind) &&
29
+ this.meta &&
30
+ this.meta.path &&
31
+ !this.longname.startsWith('<anonymous>') &&
32
+ this.longname !== 'module:ol'
33
+ );
34
+ }).get();
35
+
36
+ // get symbols data, filter out those that are members of private classes
37
+ const symbols = [];
38
+ const defines = [];
39
+ const typedefs = [];
40
+ const externs = [];
41
+ let base = [];
42
+ const augments = {};
43
+ const symbolsByName = {};
44
+ docs
45
+ .filter(function (doc) {
46
+ let include = true;
47
+ const constructor = doc.memberof;
48
+ if (
49
+ constructor &&
50
+ constructor.substr(-1) === '_' &&
51
+ !constructor.includes('module:')
52
+ ) {
53
+ assert.strictEqual(
54
+ doc.inherited,
55
+ true,
56
+ 'Unexpected export on private class: ' + doc.longname
57
+ );
58
+ include = false;
59
+ }
60
+ return include;
61
+ })
62
+ .forEach(function (doc) {
63
+ const isExterns = /[\\\/]externs$/.test(doc.meta.path);
64
+ if (doc.define) {
65
+ defines.push({
66
+ name: doc.longname,
67
+ description: doc.description,
68
+ path: path.join(doc.meta.path, doc.meta.filename),
69
+ default: doc.define.default,
70
+ });
71
+ } else if (doc.type && (doc.kind == 'typedef' || doc.isEnum === true)) {
72
+ typedefs.push({
73
+ name: doc.longname,
74
+ types: getTypes(doc.type.names),
75
+ });
76
+ } else {
77
+ const symbol = {
78
+ name: doc.longname,
79
+ kind: doc.kind,
80
+ description: doc.classdesc || doc.description,
81
+ path: path.join(doc.meta.path, doc.meta.filename),
82
+ };
83
+ if (doc.augments) {
84
+ symbol.extends = doc.augments[0];
85
+ }
86
+ if (doc.virtual) {
87
+ symbol.virtual = true;
88
+ }
89
+ if (doc.type) {
90
+ symbol.types = getTypes(doc.type.names);
91
+ }
92
+ if (doc.params) {
93
+ const params = [];
94
+ doc.params.forEach(function (param) {
95
+ const paramInfo = {
96
+ name: param.name,
97
+ };
98
+ params.push(paramInfo);
99
+ paramInfo.types = getTypes(param.type.names);
100
+ if (typeof param.variable == 'boolean') {
101
+ paramInfo.variable = param.variable;
102
+ }
103
+ if (typeof param.optional == 'boolean') {
104
+ paramInfo.optional = param.optional;
105
+ }
106
+ if (typeof param.nullable == 'boolean') {
107
+ paramInfo.nullable = param.nullable;
108
+ }
109
+ });
110
+ symbol.params = params;
111
+ }
112
+ if (doc.returns) {
113
+ symbol.returns = {
114
+ types: getTypes(doc.returns[0].type.names),
115
+ };
116
+ if (typeof doc.returns[0].nullable == 'boolean') {
117
+ symbol.returns.nullable = doc.returns[0].nullable;
118
+ }
119
+ }
120
+ if (doc.tags) {
121
+ doc.tags.every(function (tag) {
122
+ if (tag.title == 'template') {
123
+ symbol.template = tag.value;
124
+ return false;
125
+ }
126
+ return true;
127
+ });
128
+ }
129
+ if (doc.isDefaultExport) {
130
+ symbol.isDefaultExport = true;
131
+ }
132
+
133
+ const target = isExterns ? externs : symbols;
134
+ const existingSymbol = symbolsByName[symbol.name];
135
+ if (existingSymbol) {
136
+ const idx = target.indexOf(existingSymbol);
137
+ target.splice(idx, 1);
138
+ }
139
+ target.push(symbol);
140
+ symbolsByName[symbol.name] = symbol;
141
+
142
+ if (symbol.extends) {
143
+ while (
144
+ symbol.extends in classes &&
145
+ classes[symbol.extends].augments
146
+ ) {
147
+ symbol.extends = classes[symbol.extends].augments[0];
148
+ }
149
+ if (symbol.extends) {
150
+ augments[symbol.extends] = true;
151
+ }
152
+ }
153
+ }
154
+ });
155
+
156
+ base = base.filter(function (symbol) {
157
+ return symbol.name in augments || symbol.virtual;
158
+ });
159
+
160
+ return new Promise(function (resolve, reject) {
161
+ process.stdout.write(
162
+ JSON.stringify(
163
+ {
164
+ symbols: symbols,
165
+ defines: defines,
166
+ typedefs: typedefs,
167
+ externs: externs,
168
+ base: base,
169
+ },
170
+ null,
171
+ 2
172
+ )
173
+ );
174
+ });
175
+ };
@@ -0,0 +1,4 @@
1
+ {
2
+ "description": "JSDoc loads publish.js files with require(), so we need to configure everything under this path as a CommonJS module.",
3
+ "type": "commonjs"
4
+ }
@@ -0,0 +1,181 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ /**
4
+ * Define an @api tag
5
+ * @param {Object} dictionary The tag dictionary.
6
+ */
7
+ exports.defineTags = function (dictionary) {
8
+ dictionary.defineTag('api', {
9
+ mustNotHaveValue: true,
10
+ canHaveType: false,
11
+ canHaveName: false,
12
+ onTagged: function (doclet, tag) {
13
+ includeTypes(doclet);
14
+ doclet.stability = 'stable';
15
+ },
16
+ });
17
+ };
18
+
19
+ /*
20
+ * Based on @api annotations, and assuming that items with no @api annotation
21
+ * should not be documented, this plugin removes undocumented symbols
22
+ * from the documentation.
23
+ */
24
+
25
+ const api = {};
26
+ const classes = {};
27
+ const types = {};
28
+ const modules = {};
29
+
30
+ function includeAugments(doclet) {
31
+ // Make sure that `observables` and `fires` are taken from an already processed `class` doclet.
32
+ // This is necessary because JSDoc generates multiple doclets with the same longname.
33
+ const cls = classes[doclet.longname];
34
+ if (cls.observables && !doclet.observables) {
35
+ doclet.observables = cls.observables;
36
+ }
37
+ if (doclet.fires && cls.fires) {
38
+ for (let i = 0, ii = cls.fires.length; i < ii; ++i) {
39
+ const fires = cls.fires[i];
40
+ if (!doclet.fires.includes(fires)) {
41
+ doclet.fires.push(fires);
42
+ }
43
+ }
44
+ }
45
+ if (cls.fires && !doclet.fires) {
46
+ doclet.fires = cls.fires;
47
+ }
48
+
49
+ const augments = doclet.augments;
50
+ if (augments) {
51
+ let cls;
52
+ for (let i = augments.length - 1; i >= 0; --i) {
53
+ cls = classes[augments[i]];
54
+ if (cls) {
55
+ includeAugments(cls);
56
+ if (cls.fires) {
57
+ if (!doclet.fires) {
58
+ doclet.fires = [];
59
+ }
60
+ cls.fires.forEach(function (f) {
61
+ if (!doclet.fires.includes(f)) {
62
+ doclet.fires.push(f);
63
+ }
64
+ });
65
+ }
66
+ if (cls.observables) {
67
+ if (!doclet.observables) {
68
+ doclet.observables = [];
69
+ }
70
+ cls.observables.forEach(function (f) {
71
+ if (!doclet.observables.includes(f)) {
72
+ doclet.observables.push(f);
73
+ }
74
+ });
75
+ }
76
+ cls._hideConstructor = true;
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ function extractTypes(item) {
83
+ item.type.names.forEach(function (type) {
84
+ const match = type.match(/^(?:.*<)?([^>]*)>?$/);
85
+ if (match) {
86
+ modules[match[1]] = true;
87
+ types[match[1]] = true;
88
+ }
89
+ });
90
+ }
91
+
92
+ function includeTypes(doclet) {
93
+ if (doclet.params) {
94
+ doclet.params.forEach(extractTypes);
95
+ }
96
+ if (doclet.returns) {
97
+ doclet.returns.forEach(extractTypes);
98
+ }
99
+ if (doclet.properties) {
100
+ doclet.properties.forEach(extractTypes);
101
+ }
102
+ if (doclet.type && doclet.meta.code.type == 'MemberExpression') {
103
+ extractTypes(doclet);
104
+ }
105
+ }
106
+
107
+ function sortOtherMembers(doclet) {
108
+ if (doclet.fires) {
109
+ doclet.fires.sort(function (a, b) {
110
+ return a.split(/#?event:/)[1] < b.split(/#?event:/)[1] ? -1 : 1;
111
+ });
112
+ }
113
+ if (doclet.observables) {
114
+ doclet.observables.sort(function (a, b) {
115
+ return a.name < b.name ? -1 : 1;
116
+ });
117
+ }
118
+ }
119
+
120
+ exports.handlers = {
121
+ newDoclet: function (e) {
122
+ const doclet = e.doclet;
123
+ if (doclet.stability) {
124
+ modules[doclet.longname.split(/[~\.]/).shift()] = true;
125
+ api[doclet.longname.split('#')[0]] = true;
126
+ }
127
+ if (doclet.kind == 'class') {
128
+ if (!(doclet.longname in classes)) {
129
+ classes[doclet.longname] = doclet;
130
+ } else if ('augments' in doclet) {
131
+ classes[doclet.longname].augments = doclet.augments;
132
+ }
133
+ }
134
+ if (doclet.name === doclet.longname && !doclet.memberof) {
135
+ // Make sure anonymous default exports are documented
136
+ doclet.setMemberof(doclet.longname);
137
+ }
138
+ },
139
+
140
+ parseComplete: function (e) {
141
+ const doclets = e.doclets;
142
+ const byLongname = doclets.index.longname;
143
+ for (let i = doclets.length - 1; i >= 0; --i) {
144
+ const doclet = doclets[i];
145
+ if (doclet.stability) {
146
+ if (doclet.kind == 'class') {
147
+ includeAugments(doclet);
148
+ }
149
+ sortOtherMembers(doclet);
150
+ // Always document namespaces and items with stability annotation
151
+ continue;
152
+ }
153
+ if (doclet.kind == 'module' && doclet.longname in modules) {
154
+ // Document all modules that are referenced by the API
155
+ continue;
156
+ }
157
+ if (doclet.isEnum || doclet.kind == 'typedef') {
158
+ continue;
159
+ }
160
+ if (doclet.kind == 'class' && doclet.longname in api) {
161
+ // Mark undocumented classes with documented members as unexported.
162
+ // This is used in ../template/tmpl/container.tmpl to hide the
163
+ // constructor from the docs.
164
+ doclet._hideConstructor = true;
165
+ includeAugments(doclet);
166
+ sortOtherMembers(doclet);
167
+ } else if (!doclet._hideConstructor) {
168
+ // Remove all other undocumented symbols
169
+ doclet.undocumented = true;
170
+ }
171
+ if (
172
+ doclet.memberof &&
173
+ byLongname[doclet.memberof] &&
174
+ byLongname[doclet.memberof][0].isEnum &&
175
+ !byLongname[doclet.memberof][0].properties.some((p) => p.stability)
176
+ ) {
177
+ byLongname[doclet.memberof][0].undocumented = true;
178
+ }
179
+ }
180
+ },
181
+ };
@@ -0,0 +1,35 @@
1
+ const defaultExports = {};
2
+ const path = require('path');
3
+ const moduleRoot = path.join(process.cwd(), 'src');
4
+
5
+ // Tag default exported Identifiers because their name should be the same as the module name.
6
+ exports.astNodeVisitor = {
7
+ visitNode: function (node, e, parser, currentSourceName) {
8
+ if (node.parent && node.parent.type === 'ExportDefaultDeclaration') {
9
+ const modulePath = path
10
+ .relative(moduleRoot, currentSourceName)
11
+ .replace(/\.js$/, '');
12
+ const exportName =
13
+ 'module:' +
14
+ modulePath.replace(/\\/g, '/') +
15
+ (node.name ? '~' + node.name : '');
16
+ defaultExports[exportName] = true;
17
+ }
18
+ },
19
+ };
20
+
21
+ exports.handlers = {
22
+ processingComplete(e) {
23
+ const byLongname = e.doclets.index.longname;
24
+ for (const name in defaultExports) {
25
+ if (!(name in byLongname)) {
26
+ throw new Error(
27
+ `missing ${name} in doclet index, did you forget a @module tag?`
28
+ );
29
+ }
30
+ byLongname[name].forEach(function (doclet) {
31
+ doclet.isDefaultExport = true;
32
+ });
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,33 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ /**
4
+ * @fileoverview This plugin extracts info from boolean defines. This only
5
+ * handles boolean defines with the default value in the description. Default
6
+ * is assumed to be provided with something like "default is `true`" (case
7
+ * insensitive, with or without ticks).
8
+ */
9
+
10
+ const DEFAULT_VALUE = /default\s+is\s+`?(true|false)`?/i;
11
+
12
+ /**
13
+ * Hook to define new tags.
14
+ * @param {Object} dictionary The tag dictionary.
15
+ */
16
+ exports.defineTags = function (dictionary) {
17
+ dictionary.defineTag('define', {
18
+ canHaveType: true,
19
+ mustHaveValue: true,
20
+ onTagged: function (doclet, tag) {
21
+ const types = tag.value.type.names;
22
+ if (types.length === 1 && types[0] === 'boolean') {
23
+ const match = tag.value.description.match(DEFAULT_VALUE);
24
+ if (match) {
25
+ doclet.define = {
26
+ default: match[1] === 'true',
27
+ };
28
+ doclet.description = tag.value.description;
29
+ }
30
+ }
31
+ },
32
+ });
33
+ };
@@ -0,0 +1,39 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ const events = {};
4
+
5
+ exports.handlers = {
6
+ newDoclet: function (e) {
7
+ const doclet = e.doclet;
8
+ if (doclet.kind !== 'event') {
9
+ return;
10
+ }
11
+
12
+ const cls = doclet.longname.split('#')[0];
13
+ if (!(cls in events)) {
14
+ events[cls] = [];
15
+ }
16
+ events[cls].push(doclet.longname);
17
+ },
18
+
19
+ parseComplete: function (e) {
20
+ const doclets = e.doclets;
21
+ for (let i = 0, ii = doclets.length - 1; i < ii; ++i) {
22
+ const doclet = doclets[i];
23
+ if (doclet.fires) {
24
+ if (doclet.kind == 'class') {
25
+ const fires = [];
26
+ for (let j = 0, jj = doclet.fires.length; j < jj; ++j) {
27
+ const event = doclet.fires[j].replace('event:', '');
28
+ if (events[event]) {
29
+ fires.push.apply(fires, events[event]);
30
+ } else if (doclet.fires[j] !== 'event:ObjectEvent') {
31
+ fires.push(doclet.fires[j]);
32
+ }
33
+ }
34
+ doclet.fires = fires;
35
+ }
36
+ }
37
+ }
38
+ },
39
+ };
@@ -0,0 +1,102 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ /**
4
+ * @fileoverview
5
+ * Inlines option params from typedefs
6
+ */
7
+
8
+ const properties = {};
9
+
10
+ /**
11
+ * This parses the comment for `@template` annotations and returns an object with name / type pairs for all template
12
+ * values
13
+ * @param {string} comment a jsdoc comment to parse
14
+ * @return {Object<string, string>} results
15
+ */
16
+ function parseCommentForTemplates(comment) {
17
+ let remainingText = comment;
18
+ const results = {};
19
+ while (true) {
20
+ const templateMatch = remainingText.match(/\* @template\s*([\s\S]*)/);
21
+
22
+ if (!templateMatch) {
23
+ return results;
24
+ }
25
+
26
+ remainingText = templateMatch[1];
27
+
28
+ if (remainingText[0] !== '{') {
29
+ continue;
30
+ }
31
+
32
+ let index = 1;
33
+ let openParenthesis = 1;
34
+ while (openParenthesis > 0) {
35
+ if (remainingText[index] === '{') {
36
+ openParenthesis++;
37
+ } else if (remainingText[index] === '}') {
38
+ openParenthesis--;
39
+ }
40
+ index++;
41
+ }
42
+ const type = remainingText.slice(1, index - 1);
43
+ remainingText = remainingText.slice(index);
44
+
45
+ const name = remainingText.match(/\s*(\S*)/)[1];
46
+
47
+ results[name] = type;
48
+ }
49
+ }
50
+
51
+ exports.handlers = {
52
+ /**
53
+ * Collects all typedefs, keyed by longname
54
+ * @param {Object} e Event object.
55
+ */
56
+ newDoclet: function (e) {
57
+ if (e.doclet.kind == 'typedef' && e.doclet.properties) {
58
+ properties[e.doclet.longname] = e.doclet.properties;
59
+ }
60
+ },
61
+
62
+ /**
63
+ * Adds `options.*` params for options that match the longname of one of the
64
+ * collected typedefs.
65
+ * @param {Object} e Event object.
66
+ */
67
+ parseComplete: function (e) {
68
+ const doclets = e.doclets;
69
+
70
+ for (let i = 0, ii = doclets.length; i < ii; ++i) {
71
+ const doclet = doclets[i];
72
+ if (doclet.params) {
73
+ const params = doclet.params;
74
+ for (let j = 0, jj = params.length; j < jj; ++j) {
75
+ const param = params[j];
76
+ if (param.type && param.type.names) {
77
+ let type = param.type.names[0];
78
+ const genericMatches = type.match(/(^.*?)\.?<.*>/);
79
+ if (genericMatches) {
80
+ type = genericMatches[1];
81
+ }
82
+ if (type in properties) {
83
+ const templateInfo = parseCommentForTemplates(doclet.comment);
84
+ params.push.apply(
85
+ params,
86
+ properties[type].map((p) => {
87
+ const property = Object.assign({}, p);
88
+ property.name = `${param.name}.${property.name}`;
89
+ if (property.type.names[0] in templateInfo) {
90
+ property.type.names[0] =
91
+ templateInfo[property.type.names[0]];
92
+ }
93
+ return property;
94
+ })
95
+ );
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ },
102
+ };
@@ -0,0 +1,119 @@
1
+ /* eslint-disable import/no-commonjs */
2
+
3
+ /**
4
+ * Modified from JSDoc's plugins/markdown and lib/jsdoc/util/markdown modules
5
+ * (see https://github.com/jsdoc3/jsdoc/), which are licensed under the Apache 2
6
+ * license (see https://www.apache.org/licenses/LICENSE-2.0).
7
+ *
8
+ * This version does not protect http(s) urls from being turned into links, and
9
+ * works around an issue with `~` characters in module paths by escaping them.
10
+ */
11
+
12
+ const {marked} = require('marked');
13
+ const format = require('util').format;
14
+
15
+ const tags = [
16
+ 'author',
17
+ 'classdesc',
18
+ 'description',
19
+ 'exceptions',
20
+ 'params',
21
+ 'properties',
22
+ 'returns',
23
+ 'see',
24
+ 'summary',
25
+ ];
26
+
27
+ const hasOwnProp = Object.prototype.hasOwnProperty;
28
+
29
+ const markedRenderer = new marked.Renderer();
30
+
31
+ // Allow prettyprint to work on inline code samples
32
+ markedRenderer.code = function (code, language) {
33
+ const langClass = language ? ' lang-' + language : '';
34
+
35
+ return format(
36
+ '<pre class="prettyprint source%s"><code>%s</code></pre>',
37
+ langClass,
38
+ escapeCode(code)
39
+ );
40
+ };
41
+
42
+ function escapeCode(source) {
43
+ return source
44
+ .replace(/</g, '&lt;')
45
+ .replace(/"/g, '&quot;')
46
+ .replace(/'/g, '&#39;');
47
+ }
48
+
49
+ function escapeUnderscoresAndTildes(source) {
50
+ return source.replace(/\{@[^}\r\n]+\}/g, function (wholeMatch) {
51
+ return wholeMatch.replace(/(^|[^\\])_/g, '$1\\_').replace('~', '&tilde;');
52
+ });
53
+ }
54
+
55
+ function unencodeQuotesAndTildes(source) {
56
+ return source.replace(/\{@[^}\r\n]+\}/g, function (wholeMatch) {
57
+ return wholeMatch.replace(/&quot;/g, '"').replace(/&tilde;/g, '~');
58
+ });
59
+ }
60
+
61
+ function parse(source) {
62
+ let result;
63
+
64
+ source = escapeUnderscoresAndTildes(source);
65
+
66
+ result = marked(source, {
67
+ renderer: markedRenderer,
68
+ headerIds: false,
69
+ mangle: false,
70
+ })
71
+ .replace(/\s+$/, '')
72
+ .replace(/&#39;/g, "'");
73
+
74
+ result = unencodeQuotesAndTildes(result);
75
+
76
+ return result;
77
+ }
78
+
79
+ function shouldProcessString(tagName, text) {
80
+ let shouldProcess = true;
81
+
82
+ // we only want to process `@author` and `@see` tags that contain Markdown links
83
+ if ((tagName === 'author' || tagName === 'see') && !text.includes('[')) {
84
+ shouldProcess = false;
85
+ }
86
+
87
+ return shouldProcess;
88
+ }
89
+
90
+ function process(doclet) {
91
+ tags.forEach(function (tag) {
92
+ if (!hasOwnProp.call(doclet, tag)) {
93
+ return;
94
+ }
95
+
96
+ if (
97
+ typeof doclet[tag] === 'string' &&
98
+ shouldProcessString(tag, doclet[tag])
99
+ ) {
100
+ doclet[tag] = parse(doclet[tag]);
101
+ } else if (Array.isArray(doclet[tag])) {
102
+ doclet[tag].forEach(function (value, index, original) {
103
+ const inner = {};
104
+
105
+ inner[tag] = value;
106
+ process(inner);
107
+ original[index] = inner[tag];
108
+ });
109
+ } else if (doclet[tag]) {
110
+ process(doclet[tag]);
111
+ }
112
+ });
113
+ }
114
+
115
+ exports.handlers = {
116
+ newDoclet: function (e) {
117
+ process(e.doclet);
118
+ },
119
+ };