@weborigami/origami 0.0.35

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 (140) hide show
  1. package/LICENSE +21 -0
  2. package/ReadMe.md +3 -0
  3. package/exports/PathTransform.d.ts +5 -0
  4. package/exports/PathTransform.js +18 -0
  5. package/exports/buildExports.js +109 -0
  6. package/exports/exports.js +121 -0
  7. package/index.ts +25 -0
  8. package/package.json +40 -0
  9. package/src/builtins/!.js +21 -0
  10. package/src/builtins/@apply.js +6 -0
  11. package/src/builtins/@arrows.js +34 -0
  12. package/src/builtins/@builtins.js +18 -0
  13. package/src/builtins/@cache.js +36 -0
  14. package/src/builtins/@config.js +25 -0
  15. package/src/builtins/@copy.js +71 -0
  16. package/src/builtins/@crawl.js +507 -0
  17. package/src/builtins/@debug.js +89 -0
  18. package/src/builtins/@document.js +18 -0
  19. package/src/builtins/@equals.js +6 -0
  20. package/src/builtins/@explore.js +68 -0
  21. package/src/builtins/@false.js +1 -0
  22. package/src/builtins/@files.js +22 -0
  23. package/src/builtins/@filter.js +23 -0
  24. package/src/builtins/@globs.js +23 -0
  25. package/src/builtins/@help.js +49 -0
  26. package/src/builtins/@http.js +19 -0
  27. package/src/builtins/@https.js +19 -0
  28. package/src/builtins/@if.js +27 -0
  29. package/src/builtins/@image/format.js +5 -0
  30. package/src/builtins/@image/resize.js +5 -0
  31. package/src/builtins/@index.js +72 -0
  32. package/src/builtins/@inherited.js +17 -0
  33. package/src/builtins/@inline.js +29 -0
  34. package/src/builtins/@invoke.js +30 -0
  35. package/src/builtins/@js.js +33 -0
  36. package/src/builtins/@json.js +22 -0
  37. package/src/builtins/@loaders/css.js +4 -0
  38. package/src/builtins/@loaders/htm.js +4 -0
  39. package/src/builtins/@loaders/html.js +4 -0
  40. package/src/builtins/@loaders/js.js +14 -0
  41. package/src/builtins/@loaders/json.js +8 -0
  42. package/src/builtins/@loaders/md.js +4 -0
  43. package/src/builtins/@loaders/mjs.js +4 -0
  44. package/src/builtins/@loaders/ori.js +21 -0
  45. package/src/builtins/@loaders/orit.js +48 -0
  46. package/src/builtins/@loaders/txt.js +33 -0
  47. package/src/builtins/@loaders/xhtml.js +4 -0
  48. package/src/builtins/@loaders/yaml.js +18 -0
  49. package/src/builtins/@loaders/yml.js +4 -0
  50. package/src/builtins/@map.js +182 -0
  51. package/src/builtins/@match.js +92 -0
  52. package/src/builtins/@mdHtml.js +45 -0
  53. package/src/builtins/@new.js +6 -0
  54. package/src/builtins/@node.js +15 -0
  55. package/src/builtins/@not.js +6 -0
  56. package/src/builtins/@or.js +6 -0
  57. package/src/builtins/@ori.js +83 -0
  58. package/src/builtins/@pack.js +13 -0
  59. package/src/builtins/@parse/json.js +7 -0
  60. package/src/builtins/@parse/yaml.js +9 -0
  61. package/src/builtins/@project.js +71 -0
  62. package/src/builtins/@repeat.js +8 -0
  63. package/src/builtins/@rss.js +49 -0
  64. package/src/builtins/@scope/extend.js +22 -0
  65. package/src/builtins/@scope/get.js +25 -0
  66. package/src/builtins/@scope/invoke.js +22 -0
  67. package/src/builtins/@scope/set.js +25 -0
  68. package/src/builtins/@serve.js +74 -0
  69. package/src/builtins/@shell.js +16 -0
  70. package/src/builtins/@stdin.js +26 -0
  71. package/src/builtins/@svg.js +42 -0
  72. package/src/builtins/@tree/concat.js +21 -0
  73. package/src/builtins/@tree/count.js +24 -0
  74. package/src/builtins/@tree/defineds.js +37 -0
  75. package/src/builtins/@tree/dot.js +201 -0
  76. package/src/builtins/@tree/exceptions.js +50 -0
  77. package/src/builtins/@tree/first.js +28 -0
  78. package/src/builtins/@tree/flowSvg.js +55 -0
  79. package/src/builtins/@tree/fn.js +34 -0
  80. package/src/builtins/@tree/from.js +27 -0
  81. package/src/builtins/@tree/fromJson.js +6 -0
  82. package/src/builtins/@tree/fromYaml.js +24 -0
  83. package/src/builtins/@tree/groupBy.js +39 -0
  84. package/src/builtins/@tree/inners.js +44 -0
  85. package/src/builtins/@tree/isAsyncTree.js +17 -0
  86. package/src/builtins/@tree/keys.js +24 -0
  87. package/src/builtins/@tree/keysJson.js +44 -0
  88. package/src/builtins/@tree/map.d.ts +19 -0
  89. package/src/builtins/@tree/merge.js +47 -0
  90. package/src/builtins/@tree/mergeDeep.js +44 -0
  91. package/src/builtins/@tree/nextKey.js +29 -0
  92. package/src/builtins/@tree/parent.js +24 -0
  93. package/src/builtins/@tree/paths.js +35 -0
  94. package/src/builtins/@tree/plain.js +22 -0
  95. package/src/builtins/@tree/previousKey.js +29 -0
  96. package/src/builtins/@tree/reverse.js +51 -0
  97. package/src/builtins/@tree/setDeep.js +45 -0
  98. package/src/builtins/@tree/shuffle.js +31 -0
  99. package/src/builtins/@tree/sitemap.js +59 -0
  100. package/src/builtins/@tree/sort.js +25 -0
  101. package/src/builtins/@tree/sortBy.js +40 -0
  102. package/src/builtins/@tree/static.js +51 -0
  103. package/src/builtins/@tree/table.js +74 -0
  104. package/src/builtins/@tree/take.js +40 -0
  105. package/src/builtins/@tree/values.js +23 -0
  106. package/src/builtins/@tree/valuesDeep.js +23 -0
  107. package/src/builtins/@treeHttp.js +19 -0
  108. package/src/builtins/@treeHttps.js +19 -0
  109. package/src/builtins/@true.js +1 -0
  110. package/src/builtins/@unpack.js +13 -0
  111. package/src/builtins/@watch.js +108 -0
  112. package/src/builtins/@with.js +22 -0
  113. package/src/builtins/@yaml.js +23 -0
  114. package/src/builtins/~.js +9 -0
  115. package/src/cli/cli.js +86 -0
  116. package/src/cli/defaultModuleExport.js +16 -0
  117. package/src/cli/showUsage.js +86 -0
  118. package/src/common/CommandModulesTransform.d.ts +5 -0
  119. package/src/common/CommandModulesTransform.js +37 -0
  120. package/src/common/ConstantTree.js +17 -0
  121. package/src/common/ExplorableSiteTransform.d.ts +5 -0
  122. package/src/common/ExplorableSiteTransform.js +77 -0
  123. package/src/common/FilterTree.js +60 -0
  124. package/src/common/GlobTree.js +67 -0
  125. package/src/common/ShuffleTransform.js +29 -0
  126. package/src/common/TextDocument.js +57 -0
  127. package/src/common/addValueKeyToScope.js +30 -0
  128. package/src/common/arrowFunctionsMap.js +35 -0
  129. package/src/common/processUnpackedContent.js +39 -0
  130. package/src/common/serialize.d.ts +8 -0
  131. package/src/common/serialize.js +138 -0
  132. package/src/common/utilities.d.ts +7 -0
  133. package/src/common/utilities.js +132 -0
  134. package/src/misc/OriCommandTransform.d.ts +5 -0
  135. package/src/misc/OriCommandTransform.js +54 -0
  136. package/src/misc/assertScopeIsDefined.js +7 -0
  137. package/src/misc/explore.orit +241 -0
  138. package/src/misc/yamlOrigamiTag.js +17 -0
  139. package/src/server/mediaTypes.js +97 -0
  140. package/src/server/server.js +258 -0
@@ -0,0 +1,132 @@
1
+ import { Tree, isPlainObject, isStringLike } from "@weborigami/async-tree";
2
+
3
+ const textDecoder = new TextDecoder();
4
+ const TypedArray = Object.getPrototypeOf(Uint8Array);
5
+
6
+ export function isTransformApplied(Transform, obj) {
7
+ let transformName = Transform.name;
8
+ if (!transformName) {
9
+ throw `isTransformApplied was called on an unnamed transform function, but a name is required.`;
10
+ }
11
+ if (transformName.endsWith("Transform")) {
12
+ transformName = transformName.slice(0, -9);
13
+ }
14
+ // Walk up prototype chain looking for a constructor with the same name as the
15
+ // transform. This is not a great test.
16
+ for (let proto = obj; proto; proto = Object.getPrototypeOf(proto)) {
17
+ if (proto.constructor.name === transformName) {
18
+ return true;
19
+ }
20
+ }
21
+ return false;
22
+ }
23
+
24
+ export const keySymbol = Symbol("key");
25
+
26
+ export const parentSymbol = Symbol("parent");
27
+
28
+ /**
29
+ * Convert the given object to a function.
30
+ *
31
+ * @typedef {import("../../index.ts").Invocable} Invocable
32
+ * @param {any} obj
33
+ * @returns {Function}
34
+ */
35
+ export function toFunction(obj) {
36
+ if (typeof obj === "function") {
37
+ // Return a function as is.
38
+ return obj;
39
+ } else if (
40
+ typeof obj === "object" &&
41
+ typeof (/** @type {any} */ (obj)?.unpack) === "function"
42
+ ) {
43
+ // Extract the contents of the object and convert that to a function.
44
+ let fn;
45
+ /** @this {any} */
46
+ return async function (...args) {
47
+ if (!fn) {
48
+ const content = await /** @type {any} */ (obj).unpack();
49
+ fn = toFunction(content);
50
+ }
51
+ return fn.call(this, ...args);
52
+ };
53
+ } else if (Tree.isTreelike(obj)) {
54
+ // Return a function that invokes the tree's getter.
55
+ return Tree.toFunction(obj);
56
+ } else {
57
+ // Return a constant function.
58
+ return () => obj;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Return a string form of the object, handling two cases not generally handled
64
+ * by a .toString() method:
65
+ *
66
+ * 1. If the object is a plain JavaScript object with a `@text` property, return
67
+ * the value of that property.
68
+ * 2. If the object is an ArrayBuffer or TypedArray, decode the array as UTF-8.
69
+ *
70
+ * Finally, if the object is otherwise a plain JavaScript object with the
71
+ * useless default toString() method, return null instead of "[object Object]".
72
+ * In practice, it's generally more useful to have this method fail than to
73
+ * return a useless string.
74
+ *
75
+ * @param {any} object
76
+ * @returns {string|null}
77
+ */
78
+ export function toString(object) {
79
+ if (isPlainObject(object) && "@text" in object) {
80
+ return object["@text"];
81
+ } else if (object instanceof ArrayBuffer || object instanceof TypedArray) {
82
+ // Serialize data as UTF-8.
83
+ return textDecoder.decode(object);
84
+ } else if (isStringLike(object)) {
85
+ return String(object);
86
+ } else {
87
+ return null;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Apply a functional class mixin to an individual object instance.
93
+ *
94
+ * This works by create an intermediate class, creating an instance of that, and
95
+ * then setting the intermediate class's prototype to the given individual
96
+ * object. The resulting, extended object is then returned.
97
+ *
98
+ * This manipulation of the prototype chain is generally sound in JavaScript,
99
+ * with some caveats. In particular, the original object class cannot make
100
+ * direct use of private members; JavaScript will complain if the extended
101
+ * object does anything that requires access to those private members.
102
+ *
103
+ * @param {Function} Transform
104
+ * @param {any} obj
105
+ */
106
+ export function transformObject(Transform, obj) {
107
+ // Apply the mixin to Object and instantiate that. The Object base class here
108
+ // is going to be cut out of the prototype chain in a moment; we just use
109
+ // Object as a convenience because its constructor takes no arguments.
110
+ const mixed = new (Transform(Object))();
111
+
112
+ // Find the highest prototype in the chain that was added by the class mixin.
113
+ // The mixin may have added multiple prototypes to the chain. Walk up the
114
+ // prototype chain until we hit Object.
115
+ let mixinProto = Object.getPrototypeOf(mixed);
116
+ while (Object.getPrototypeOf(mixinProto) !== Object.prototype) {
117
+ mixinProto = Object.getPrototypeOf(mixinProto);
118
+ }
119
+
120
+ // Redirect the prototype chain above the mixin to point to the original
121
+ // object. The mixed object now extends the original object with the mixin.
122
+ Object.setPrototypeOf(mixinProto, obj);
123
+
124
+ // Create a new constructor for this mixed object that reflects its prototype
125
+ // chain. Because we've already got the instance we want, we won't use this
126
+ // constructor now, but this can be used later to instantiate other objects
127
+ // that look like the mixed one.
128
+ mixed.constructor = Transform(obj.constructor);
129
+
130
+ // Return the mixed object.
131
+ return mixed;
132
+ }
@@ -0,0 +1,5 @@
1
+ import { Mixin } from "@weborigami/language";
2
+
3
+ declare const OriCommandTransform: Mixin<{}>;
4
+
5
+ export default OriCommandTransform;
@@ -0,0 +1,54 @@
1
+ /** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
2
+ import { ObjectTree, Tree } from "@weborigami/async-tree";
3
+ import { Scope } from "@weborigami/language";
4
+ import ori from "../builtins/@ori.js";
5
+ import {
6
+ isTransformApplied,
7
+ keySymbol,
8
+ transformObject,
9
+ } from "../common/utilities.js";
10
+
11
+ /**
12
+ * Add support for commands prefixed with `!`.
13
+ *
14
+ * E.g., asking this tree for `!yaml` will invoke the yaml() builtin function
15
+ * in the context of this tree.
16
+ *
17
+ * @typedef {import("../../index.js").Constructor<AsyncTree>} AsyncTreeConstructor
18
+ * @param {AsyncTreeConstructor} Base
19
+ */
20
+ export default function OriCommandTransform(Base) {
21
+ return class OriCommand extends Base {
22
+ async get(key) {
23
+ let value = await super.get(key);
24
+
25
+ if (value === undefined) {
26
+ if (
27
+ key === undefined ||
28
+ typeof key !== "string" ||
29
+ !key.startsWith?.("!")
30
+ ) {
31
+ return undefined;
32
+ }
33
+ // Key is an Origami command; invoke it.
34
+ const ambientsTree = new ObjectTree({
35
+ "@current": this,
36
+ });
37
+ ambientsTree[keySymbol] = "ori command";
38
+ const extendedScope = new Scope(ambientsTree, Scope.getScope(this));
39
+ const source = key.slice(1).trim();
40
+ value = await ori.call(extendedScope, source);
41
+
42
+ // Ensure this transform is applied to any subtree.
43
+ if (
44
+ Tree.isAsyncTree(value) &&
45
+ !isTransformApplied(OriCommandTransform, value)
46
+ ) {
47
+ value = transformObject(OriCommandTransform, value);
48
+ }
49
+ }
50
+
51
+ return value;
52
+ }
53
+ };
54
+ }
@@ -0,0 +1,7 @@
1
+ export default function assertScopeIsDefined(scope) {
2
+ if (scope === undefined) {
3
+ throw new Error(
4
+ "Tree methods must be called a scope. If you don't want to pass a scope, invoke with: <methodName>.call(null)"
5
+ );
6
+ }
7
+ }
@@ -0,0 +1,241 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
6
+ <title>Graph Origami Explorer</title>
7
+ <style>
8
+ * {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ html {
13
+ height: 100%;
14
+ }
15
+
16
+ body {
17
+ background: #333;
18
+ color: #eee;
19
+ display: grid;
20
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
21
+ font-size: 13px;
22
+ grid-template-columns: 200px 1fr;
23
+ grid-template-rows: minMax(0, 1fr);
24
+ height: 100%;
25
+ margin: 0;
26
+ overflow: hidden;
27
+ }
28
+
29
+ nav {
30
+ display: grid;
31
+ gap: 1em;
32
+ grid-auto-rows: min-content;
33
+ grid-template-columns: minmax(0, 1fr);
34
+ overflow: auto;
35
+ padding: 1em 0.5em;
36
+ }
37
+
38
+ #label {
39
+ font-weight: bold;
40
+ }
41
+
42
+ #scopeToolbar {
43
+ display: grid;
44
+ grid-template-columns: repeat(4, auto);
45
+ }
46
+
47
+ button {
48
+ background: transparent;
49
+ border: solid 1px #555;
50
+ color: inherit;
51
+ font-size: smaller;
52
+ font-family: inherit;
53
+ font-weight: inherit;
54
+ padding: 0.25em;
55
+ }
56
+ button:hover {
57
+ border-color: #999;
58
+ }
59
+ button:active {
60
+ border-color: #eee;
61
+ }
62
+ button[aria-pressed="true"] {
63
+ background: #555;
64
+ }
65
+
66
+ ul {
67
+ list-style: none;
68
+ margin: 0;
69
+ padding: 0;
70
+ }
71
+
72
+ h2 {
73
+ color: #999;
74
+ font-size: inherit;
75
+ margin: 0.25em 0;
76
+ padding-left: 0.25em;
77
+ }
78
+
79
+ li {
80
+ padding: 0.25em;
81
+ padding-left: 1em;
82
+ text-indent: -0.75em;
83
+ }
84
+
85
+ a {
86
+ color: inherit;
87
+ text-decoration: none;
88
+ }
89
+
90
+ iframe {
91
+ background: white;
92
+ border: none;
93
+ height: 100%;
94
+ width: 100%;
95
+ }
96
+ </style>
97
+ <script>
98
+ let defaultPath;
99
+ let path;
100
+ let frame;
101
+
102
+ const modes = {
103
+ Content: "",
104
+ Index: "!@index",
105
+ YAML: "!@yaml",
106
+ SVG: "!@svg",
107
+ };
108
+
109
+ // Extract the path from the URL hash.
110
+ function getPathFromHash() {
111
+ return window.location.hash.slice(1); // Remove `#`
112
+ }
113
+
114
+ function getModeFromLocation() {
115
+ const href = document.location.href;
116
+ const match = /[\/](?<command>\!(?:@index|@yaml|@svg))$/.exec(href);
117
+ const command = match?.groups.command ?? "";
118
+ const mode = Object.keys(modes).find(key => modes[key] === command) ?? "Content";
119
+ return mode;
120
+ }
121
+
122
+ function removeDocumentPath(path) {
123
+ const documentPath = document.location.pathname;
124
+ if (path.startsWith(documentPath)) {
125
+ // Remove the document path prefix.
126
+ path = path.slice(documentPath.length);
127
+ }
128
+ if (path.startsWith("/")) {
129
+ // Remove the leading slash.
130
+ path = path.slice(1);
131
+ }
132
+ return path;
133
+ }
134
+
135
+ function selectMode(newMode) {
136
+ const currentMode = getModeFromLocation();
137
+ if (newMode !== currentMode) {
138
+ let newPath = removeDocumentPath(frame.contentDocument.location.pathname);
139
+ const currentExtension = modes[currentMode];
140
+ if (currentExtension && newPath.endsWith(currentExtension)) {
141
+ // Remove the current extension.
142
+ newPath = newPath.slice(0, -currentExtension.length);
143
+ }
144
+ const newExtension = modes[newMode];
145
+ const separator = newPath.endsWith("/") ? "" : "/";
146
+ const newFullPath = `${newPath}${separator}${newExtension}`;
147
+ setPath(newFullPath);
148
+ }
149
+ }
150
+
151
+ function setPath(path) {
152
+ currentPath = path;
153
+
154
+ // Show the indicated page in the frame.
155
+ const abbreviatedPath = `/${path}`;
156
+ const fullPath = `${document.location.pathname}/${path}`;
157
+ const framePathname = frame.contentDocument.location.pathname;
158
+ if (framePathname !== abbreviatedPath && framePathname !== fullPath) {
159
+ // Use `replace` to avoid affecting browser history.
160
+ frame.contentWindow.location.replace(fullPath);
161
+ }
162
+
163
+ // If the path ends with a file name corresponding to a mode, select
164
+ // the corresponding mode button.
165
+ const mode = getModeFromLocation();
166
+ const selectedButtonId = `button${mode}`;
167
+ scopeToolbar.querySelectorAll("button").forEach(button => {
168
+ const pressed = button.id === selectedButtonId ? "true" : "false";
169
+ button.setAttribute("aria-pressed", pressed);
170
+ });
171
+ }
172
+
173
+ // When hash changes, load the indicated page.
174
+ window.addEventListener("hashchange", () => {
175
+ const hashPath = getPathFromHash();
176
+ const newPath = hashPath !== undefined ? hashPath : defaultPath;
177
+ if (newPath) {
178
+ setPath(newPath);
179
+ }
180
+ });
181
+
182
+ // Initialize
183
+ window.addEventListener("load", () => {
184
+ // Refresh title on page load.
185
+ frame = document.getElementById("frame");
186
+ frame.addEventListener("load", () => {
187
+ if (frame.contentDocument.location.href !== "about:blank") {
188
+ document.title = frame.contentDocument.title;
189
+ const newPath = removeDocumentPath(frame.contentDocument.location.pathname);
190
+ const hash = `#${newPath}`;
191
+ if (window.location.hash !== hash) {
192
+ // Use `replace` to avoid affecting browser history.
193
+ window.location.replace(hash);
194
+ }
195
+ }
196
+ });
197
+
198
+ buttonContent.addEventListener("click", () => {
199
+ selectMode("Content");
200
+ });
201
+ buttonIndex.addEventListener("click", () => {
202
+ selectMode("Index");
203
+ });
204
+ buttonYAML.addEventListener("click", () => {
205
+ selectMode("YAML");
206
+ });
207
+ buttonSVG.addEventListener("click", () => {
208
+ selectMode("SVG");
209
+ });
210
+
211
+ // Navigate to any path already in the hash.
212
+ defaultPath = getPathFromHash();
213
+ if (defaultPath) {
214
+ setPath(defaultPath);
215
+ }
216
+ })
217
+ </script>
218
+ </head>
219
+ <body>
220
+ <nav>
221
+ <div id="label">Graph Origami Explorer</div>
222
+ <div id="scopeToolbar">
223
+ <button id="buttonContent">Content</button>
224
+ <button id="buttonIndex">Index</button>
225
+ <button id="buttonSVG">SVG</button>
226
+ <button id="buttonYAML">YAML</button>
227
+ </div>
228
+ {{ @map(=`
229
+ <ul>
230
+ <h2>{{ _/name }}</h2>
231
+ {{ @map(=`
232
+ <li>
233
+ <a href="./!@explore/{{ _ }}" target="frame">{{ _ }}</a>
234
+ </li>
235
+ `)(_/keys) }}
236
+ </ul>
237
+ `)(_) }}
238
+ </nav>
239
+ <iframe id="frame" name="frame"></iframe>
240
+ </body>
241
+ </html>
@@ -0,0 +1,17 @@
1
+ import { expressionFunction } from "@weborigami/language";
2
+ import * as compile from "../../../language/src/compiler/compile.js";
3
+ /**
4
+ * A YAML tag for an Origami expression.
5
+ */
6
+ export default {
7
+ identify: expressionFunction.isExpressionFunction,
8
+
9
+ resolve(str) {
10
+ const code = compile.expression(str);
11
+ return code instanceof Array
12
+ ? expressionFunction.createExpressionFunction(code)
13
+ : code;
14
+ },
15
+
16
+ tag: "!ori",
17
+ };
@@ -0,0 +1,97 @@
1
+ // From https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
2
+ export const mediaTypeForExtension = {
3
+ ".3g2": "video/3gpp2",
4
+ ".3gp": "video/3gpp",
5
+ ".7z": "application/x-7z-compressed",
6
+ ".aac": "audio/aac",
7
+ ".abw": "application/x-abiword",
8
+ ".arc": "application/x-freearc",
9
+ ".avi": "video/x-msvideo",
10
+ ".avif": "image/avif",
11
+ ".azw": "application/vnd.amazon.ebook",
12
+ ".bin": "application/octet-stream",
13
+ ".bmp": "image/bmp",
14
+ ".bz": "application/x-bzip",
15
+ ".bz2": "application/x-bzip2",
16
+ ".csh": "application/x-csh",
17
+ ".css": "text/css",
18
+ ".csv": "text/csv",
19
+ ".doc": "application/msword",
20
+ ".docx":
21
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
22
+ ".eot": "application/vnd.ms-fontobject",
23
+ ".epub": "application/epub+zip",
24
+ ".gif": "image/gif",
25
+ ".gz": "application/gzip",
26
+ ".htm": "text/html",
27
+ ".html": "text/html",
28
+ ".ico": "image/vnd.microsoft.icon",
29
+ ".ics": "text/calendar",
30
+ ".jar": "application/java-archive",
31
+ ".jpeg": "image/jpeg",
32
+ ".jpg": "image/jpeg",
33
+ ".js": "text/javascript",
34
+ ".json": "application/json",
35
+ ".jsonld": "application/ld+json",
36
+ ".mid": "audio/midi audio/x-midi",
37
+ ".midi": "audio/midi audio/x-midi",
38
+ ".mjs": "text/javascript",
39
+ ".mp3": "audio/mpeg",
40
+ ".mpeg": "video/mpeg",
41
+ ".mpkg": "application/vnd.apple.installer+xml",
42
+ ".odp": "application/vnd.oasis.opendocument.presentation",
43
+ ".ods": "application/vnd.oasis.opendocument.spreadsheet",
44
+ ".odt": "application/vnd.oasis.opendocument.text",
45
+ ".oga": "audio/ogg",
46
+ ".ogv": "video/ogg",
47
+ ".ogx": "application/ogg",
48
+ ".opus": "audio/opus",
49
+ ".otf": "font/otf",
50
+ ".pdf": "application/pdf",
51
+ ".php": "application/x-httpd-php",
52
+ ".png": "image/png",
53
+ ".ppt": "application/vnd.ms-powerpoint",
54
+ ".pptx":
55
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
56
+ ".rar": "application/vnd.rar",
57
+ ".rtf": "application/rtf",
58
+ ".sh": "application/x-sh",
59
+ ".svg": "image/svg+xml",
60
+ ".swf": "application/x-shockwave-flash",
61
+ ".tar": "application/x-tar",
62
+ ".tif": "image/tiff",
63
+ ".tiff": "image/tiff",
64
+ ".ts": "video/mp2t",
65
+ ".ttf": "font/ttf",
66
+ ".txt": "text/plain",
67
+ ".vsd": "application/vnd.visio",
68
+ ".wav": "audio/wav",
69
+ ".weba": "audio/webm",
70
+ ".webm": "video/webm",
71
+ ".webp": "image/webp",
72
+ ".woff": "font/woff",
73
+ ".woff2": "font/woff2",
74
+ ".xhtml": "application/xhtml+xml",
75
+ ".xls": "application/vnd.ms-excel",
76
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
77
+ ".xml": "application/xml",
78
+ ".xul": "application/vnd.mozilla.xul+xml",
79
+ ".yaml": "text/yaml", // Not official
80
+ ".zip": "application/zip",
81
+ };
82
+
83
+ export const mediaTypeIsText = {
84
+ "application/json": true,
85
+ "application/ld+json": true,
86
+ "application/vnd.oasis.opendocument.text": true,
87
+ "application/x-httpd-php": true,
88
+ "application/x-sh": true,
89
+ "application/xhtml+xml": true,
90
+ "text/css": true,
91
+ "text/csv": true,
92
+ "text/html": true,
93
+ "text/javascript": true,
94
+ "text/plain": true,
95
+ "text/yaml": true,
96
+ "text/yml": true,
97
+ };