@webpieces/docs-site 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 (95) hide show
  1. package/README.md +83 -0
  2. package/package.json +28 -0
  3. package/src/DocsSiteError.d.ts +24 -0
  4. package/src/DocsSiteError.js +33 -0
  5. package/src/DocsSiteError.js.map +1 -0
  6. package/src/assets/SiteScript.d.ts +11 -0
  7. package/src/assets/SiteScript.js +88 -0
  8. package/src/assets/SiteScript.js.map +1 -0
  9. package/src/assets/SiteStyles.d.ts +13 -0
  10. package/src/assets/SiteStyles.js +106 -0
  11. package/src/assets/SiteStyles.js.map +1 -0
  12. package/src/cli/DocsSiteCli.d.ts +37 -0
  13. package/src/cli/DocsSiteCli.js +116 -0
  14. package/src/cli/DocsSiteCli.js.map +1 -0
  15. package/src/cli/WpDocsSiteMain.d.ts +21 -0
  16. package/src/cli/WpDocsSiteMain.js +60 -0
  17. package/src/cli/WpDocsSiteMain.js.map +1 -0
  18. package/src/cli/wp-docs-site.d.ts +2 -0
  19. package/src/cli/wp-docs-site.js +22 -0
  20. package/src/cli/wp-docs-site.js.map +1 -0
  21. package/src/emit/SiteWriter.d.ts +13 -0
  22. package/src/emit/SiteWriter.js +34 -0
  23. package/src/emit/SiteWriter.js.map +1 -0
  24. package/src/index.d.ts +41 -0
  25. package/src/index.js +105 -0
  26. package/src/index.js.map +1 -0
  27. package/src/manifest/DocsManifest.d.ts +28 -0
  28. package/src/manifest/DocsManifest.js +44 -0
  29. package/src/manifest/DocsManifest.js.map +1 -0
  30. package/src/manifest/ProseLoader.d.ts +23 -0
  31. package/src/manifest/ProseLoader.js +81 -0
  32. package/src/manifest/ProseLoader.js.map +1 -0
  33. package/src/markdown/Markdown.d.ts +47 -0
  34. package/src/markdown/Markdown.js +178 -0
  35. package/src/markdown/Markdown.js.map +1 -0
  36. package/src/render/CardRenderer.d.ts +28 -0
  37. package/src/render/CardRenderer.js +70 -0
  38. package/src/render/CardRenderer.js.map +1 -0
  39. package/src/render/FieldTreeRenderer.d.ts +34 -0
  40. package/src/render/FieldTreeRenderer.js +91 -0
  41. package/src/render/FieldTreeRenderer.js.map +1 -0
  42. package/src/render/Html.d.ts +14 -0
  43. package/src/render/Html.js +28 -0
  44. package/src/render/Html.js.map +1 -0
  45. package/src/render/Layout.d.ts +21 -0
  46. package/src/render/Layout.js +74 -0
  47. package/src/render/Layout.js.map +1 -0
  48. package/src/render/NavModel.d.ts +47 -0
  49. package/src/render/NavModel.js +86 -0
  50. package/src/render/NavModel.js.map +1 -0
  51. package/src/render/OperationPageRenderer.d.ts +44 -0
  52. package/src/render/OperationPageRenderer.js +102 -0
  53. package/src/render/OperationPageRenderer.js.map +1 -0
  54. package/src/render/SitePage.d.ts +30 -0
  55. package/src/render/SitePage.js +46 -0
  56. package/src/render/SitePage.js.map +1 -0
  57. package/src/render/SiteRenderer.d.ts +34 -0
  58. package/src/render/SiteRenderer.js +121 -0
  59. package/src/render/SiteRenderer.js.map +1 -0
  60. package/src/render/SiteUrls.d.ts +24 -0
  61. package/src/render/SiteUrls.js +37 -0
  62. package/src/render/SiteUrls.js.map +1 -0
  63. package/src/samples/CodeSamples.d.ts +49 -0
  64. package/src/samples/CodeSamples.js +166 -0
  65. package/src/samples/CodeSamples.js.map +1 -0
  66. package/src/serve/DevServer.d.ts +35 -0
  67. package/src/serve/DevServer.js +109 -0
  68. package/src/serve/DevServer.js.map +1 -0
  69. package/src/spec/ApiSpec.d.ts +110 -0
  70. package/src/spec/ApiSpec.js +165 -0
  71. package/src/spec/ApiSpec.js.map +1 -0
  72. package/src/spec/ExampleBuilder.d.ts +32 -0
  73. package/src/spec/ExampleBuilder.js +119 -0
  74. package/src/spec/ExampleBuilder.js.map +1 -0
  75. package/src/spec/FieldTree.d.ts +75 -0
  76. package/src/spec/FieldTree.js +155 -0
  77. package/src/spec/FieldTree.js.map +1 -0
  78. package/src/spec/JsonNode.d.ts +53 -0
  79. package/src/spec/JsonNode.js +93 -0
  80. package/src/spec/JsonNode.js.map +1 -0
  81. package/src/spec/SchemaLens.d.ts +57 -0
  82. package/src/spec/SchemaLens.js +162 -0
  83. package/src/spec/SchemaLens.js.map +1 -0
  84. package/src/spec/SchemaShape.d.ts +22 -0
  85. package/src/spec/SchemaShape.js +61 -0
  86. package/src/spec/SchemaShape.js.map +1 -0
  87. package/src/spec/Slug.d.ts +16 -0
  88. package/src/spec/Slug.js +43 -0
  89. package/src/spec/Slug.js.map +1 -0
  90. package/src/spec/SpecLoader.d.ts +26 -0
  91. package/src/spec/SpecLoader.js +64 -0
  92. package/src/spec/SpecLoader.js.map +1 -0
  93. package/src/spec/SpecReader.d.ts +46 -0
  94. package/src/spec/SpecReader.js +174 -0
  95. package/src/spec/SpecReader.js.map +1 -0
@@ -0,0 +1,46 @@
1
+ import { ApiSpec } from './ApiSpec';
2
+ import { JsonNode } from './JsonNode';
3
+ /** The section untagged operations land in, so an operation is never unreachable from the nav. */
4
+ export declare const UNTAGGED_SECTION = "Operations";
5
+ /**
6
+ * Reads one OpenAPI 3.0-or-3.1 document into an {@link ApiSpec}.
7
+ *
8
+ * ## Nothing here is SORTED
9
+ *
10
+ * Both orders in the finished site are published decisions somebody made, so neither is re-derived:
11
+ * the reference order is the document's own `tags[]`, and the prose order is `docs.manifest.json`.
12
+ * Alphabetising either is not a cleanup — it reorders partner-facing navigation.
13
+ *
14
+ * A tag that appears on an operation without being declared in `tags[]` still gets its own section,
15
+ * appended in first-seen order. A tag missing from the sidebar is an operation a partner cannot
16
+ * find, which reads exactly like an operation that does not exist.
17
+ *
18
+ * ## Webhooks
19
+ *
20
+ * A top-level `webhooks:` entry files into the SAME section as the operations sharing its tag, and
21
+ * is APPENDED after them, because the events are what happens as a result of the calls above.
22
+ */
23
+ export declare class SpecReader {
24
+ private readonly shape;
25
+ read(root: JsonNode): ApiSpec;
26
+ private readServers;
27
+ private readSecuritySchemes;
28
+ private readSchemas;
29
+ private readSections;
30
+ /** `tags[]` first, in its published order, then any tag only an operation mentions. */
31
+ private sectionOrder;
32
+ private tagDescription;
33
+ private readOperations;
34
+ private readWebhooks;
35
+ private readOperation;
36
+ private tagOf;
37
+ private requestSchemaOf;
38
+ private responsesOf;
39
+ /**
40
+ * The credentials this operation needs: its own `security` when it states one, the document's
41
+ * otherwise. An operation stating `security: []` needs none, and that empty array is the
42
+ * OpenAPI spelling of "no credential" rather than of "inherit" — so it must not fall back.
43
+ */
44
+ private operationSecurityKeys;
45
+ private securityKeysIn;
46
+ }
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpecReader = exports.UNTAGGED_SECTION = void 0;
4
+ const ApiSpec_1 = require("./ApiSpec");
5
+ const SchemaShape_1 = require("./SchemaShape");
6
+ const Slug_1 = require("./Slug");
7
+ const HTTP_METHODS = [
8
+ 'get',
9
+ 'put',
10
+ 'post',
11
+ 'delete',
12
+ 'options',
13
+ 'head',
14
+ 'patch',
15
+ 'trace',
16
+ ];
17
+ /** The section untagged operations land in, so an operation is never unreachable from the nav. */
18
+ exports.UNTAGGED_SECTION = 'Operations';
19
+ /**
20
+ * Reads one OpenAPI 3.0-or-3.1 document into an {@link ApiSpec}.
21
+ *
22
+ * ## Nothing here is SORTED
23
+ *
24
+ * Both orders in the finished site are published decisions somebody made, so neither is re-derived:
25
+ * the reference order is the document's own `tags[]`, and the prose order is `docs.manifest.json`.
26
+ * Alphabetising either is not a cleanup — it reorders partner-facing navigation.
27
+ *
28
+ * A tag that appears on an operation without being declared in `tags[]` still gets its own section,
29
+ * appended in first-seen order. A tag missing from the sidebar is an operation a partner cannot
30
+ * find, which reads exactly like an operation that does not exist.
31
+ *
32
+ * ## Webhooks
33
+ *
34
+ * A top-level `webhooks:` entry files into the SAME section as the operations sharing its tag, and
35
+ * is APPENDED after them, because the events are what happens as a result of the calls above.
36
+ */
37
+ class SpecReader {
38
+ shape = new SchemaShape_1.SchemaShape();
39
+ read(root) {
40
+ const schemas = this.readSchemas(root);
41
+ const sections = this.readSections(root);
42
+ return new ApiSpec_1.ApiSpec(root.at('info').text('title') ?? 'API reference', root.at('info').text('version') ?? '', root.at('info').text('description') ?? '', this.readServers(root), sections, this.readSecuritySchemes(root), schemas, this.securityKeysIn(root));
43
+ }
44
+ readServers(root) {
45
+ return root
46
+ .list('servers')
47
+ .map((entry) => new ApiSpec_1.ServerInfo(entry.text('url') ?? '', entry.text('description')));
48
+ }
49
+ readSecuritySchemes(root) {
50
+ const declared = root.at('components').at('securitySchemes');
51
+ return declared
52
+ .entries()
53
+ .map((entry) => new ApiSpec_1.SecuritySchemeInfo(entry.key, entry.value.text('type') ?? '', entry.value.text('in') ?? '', entry.value.text('name') ?? '', entry.value.text('description')));
54
+ }
55
+ readSchemas(root) {
56
+ const slugs = new Slug_1.Slug();
57
+ return root
58
+ .at('components')
59
+ .at('schemas')
60
+ .entries()
61
+ .map((entry) => new ApiSpec_1.NamedSchema(entry.key, slugs.unique(entry.key), entry.value, this.shape.hasOwnPage(entry.value)));
62
+ }
63
+ readSections(root) {
64
+ const slugs = new Slug_1.Slug();
65
+ const operations = this.readOperations(root, slugs);
66
+ const webhooks = this.readWebhooks(root, slugs);
67
+ const order = this.sectionOrder(root, operations, webhooks);
68
+ const sections = [];
69
+ for (const tag of order) {
70
+ const inTag = operations.filter((one) => one.tag === tag);
71
+ const eventsInTag = webhooks.filter((one) => one.tag === tag);
72
+ sections.push(new ApiSpec_1.TagSection(tag, this.tagDescription(root, tag), [...inTag, ...eventsInTag]));
73
+ }
74
+ return sections;
75
+ }
76
+ /** `tags[]` first, in its published order, then any tag only an operation mentions. */
77
+ sectionOrder(root, operations, webhooks) {
78
+ const order = [];
79
+ for (const declared of root.list('tags')) {
80
+ const name = declared.text('name');
81
+ if (name !== undefined && !order.includes(name)) {
82
+ order.push(name);
83
+ }
84
+ }
85
+ for (const one of [...operations, ...webhooks]) {
86
+ if (!order.includes(one.tag)) {
87
+ order.push(one.tag);
88
+ }
89
+ }
90
+ return order.filter((tag) => [...operations, ...webhooks].some((one) => one.tag === tag));
91
+ }
92
+ tagDescription(root, tag) {
93
+ for (const declared of root.list('tags')) {
94
+ if (declared.text('name') === tag) {
95
+ return declared.text('description') ?? '';
96
+ }
97
+ }
98
+ return '';
99
+ }
100
+ readOperations(root, slugs) {
101
+ const found = [];
102
+ for (const pathEntry of root.at('paths').entries()) {
103
+ for (const methodEntry of pathEntry.value.entries()) {
104
+ if (!HTTP_METHODS.includes(methodEntry.key)) {
105
+ continue;
106
+ }
107
+ found.push(this.readOperation(root, methodEntry.value, slugs, methodEntry.key.toUpperCase(), pathEntry.key, false));
108
+ }
109
+ }
110
+ return found;
111
+ }
112
+ readWebhooks(root, slugs) {
113
+ const found = [];
114
+ for (const eventEntry of root.at('webhooks').entries()) {
115
+ for (const methodEntry of eventEntry.value.entries()) {
116
+ if (!HTTP_METHODS.includes(methodEntry.key)) {
117
+ continue;
118
+ }
119
+ found.push(this.readOperation(root, methodEntry.value, slugs, '', eventEntry.key, true));
120
+ }
121
+ }
122
+ return found;
123
+ }
124
+ readOperation(root, node, slugs, httpMethod, pathOrEvent, isWebhook) {
125
+ const name = node.text('summary') ?? node.text('operationId') ?? pathOrEvent;
126
+ return new ApiSpec_1.OperationInfo(name, slugs.unique(name), httpMethod, isWebhook ? '' : pathOrEvent, node.text('description') ?? '', this.tagOf(node), this.requestSchemaOf(node), this.responsesOf(node), isWebhook, isWebhook ? [] : this.operationSecurityKeys(root, node), isWebhook ? pathOrEvent : '');
127
+ }
128
+ tagOf(node) {
129
+ for (const tag of node.list('tags')) {
130
+ const name = tag.asText();
131
+ if (name !== undefined) {
132
+ return name;
133
+ }
134
+ }
135
+ return exports.UNTAGGED_SECTION;
136
+ }
137
+ requestSchemaOf(node) {
138
+ const schema = node.at('requestBody').at('content').at('application/json').at('schema');
139
+ return schema.isObject() ? schema : undefined;
140
+ }
141
+ responsesOf(node) {
142
+ return node
143
+ .at('responses')
144
+ .entries()
145
+ .map((entry) => {
146
+ const schema = entry.value.at('content').at('application/json').at('schema');
147
+ return new ApiSpec_1.ResponseInfo(entry.key, entry.value.text('description') ?? '', schema.isObject() ? schema : undefined);
148
+ });
149
+ }
150
+ /**
151
+ * The credentials this operation needs: its own `security` when it states one, the document's
152
+ * otherwise. An operation stating `security: []` needs none, and that empty array is the
153
+ * OpenAPI spelling of "no credential" rather than of "inherit" — so it must not fall back.
154
+ */
155
+ operationSecurityKeys(root, node) {
156
+ if (Array.isArray(node.at('security').raw)) {
157
+ return this.securityKeysIn(node);
158
+ }
159
+ return this.securityKeysIn(root);
160
+ }
161
+ securityKeysIn(holder) {
162
+ const keys = [];
163
+ for (const requirement of holder.list('security')) {
164
+ for (const key of requirement.keys()) {
165
+ if (!keys.includes(key)) {
166
+ keys.push(key);
167
+ }
168
+ }
169
+ }
170
+ return keys;
171
+ }
172
+ }
173
+ exports.SpecReader = SpecReader;
174
+ //# sourceMappingURL=SpecReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SpecReader.js","sourceRoot":"","sources":["../../../../../../packages/docs/docs-site/src/spec/SpecReader.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n ApiSpec,\n NamedSchema,\n OperationInfo,\n ResponseInfo,\n SecuritySchemeInfo,\n ServerInfo,\n TagSection,\n} from './ApiSpec';\nimport { JsonEntry, JsonNode } from './JsonNode';\nimport { SchemaShape } from './SchemaShape';\nimport { Slug } from './Slug';\n\nconst HTTP_METHODS: readonly string[] = [\n 'get',\n 'put',\n 'post',\n 'delete',\n 'options',\n 'head',\n 'patch',\n 'trace',\n];\n\n/** The section untagged operations land in, so an operation is never unreachable from the nav. */\nexport const UNTAGGED_SECTION = 'Operations';\n\n/**\n * Reads one OpenAPI 3.0-or-3.1 document into an {@link ApiSpec}.\n *\n * ## Nothing here is SORTED\n *\n * Both orders in the finished site are published decisions somebody made, so neither is re-derived:\n * the reference order is the document's own `tags[]`, and the prose order is `docs.manifest.json`.\n * Alphabetising either is not a cleanup — it reorders partner-facing navigation.\n *\n * A tag that appears on an operation without being declared in `tags[]` still gets its own section,\n * appended in first-seen order. A tag missing from the sidebar is an operation a partner cannot\n * find, which reads exactly like an operation that does not exist.\n *\n * ## Webhooks\n *\n * A top-level `webhooks:` entry files into the SAME section as the operations sharing its tag, and\n * is APPENDED after them, because the events are what happens as a result of the calls above.\n */\nexport class SpecReader {\n private readonly shape = new SchemaShape();\n\n read(root: JsonNode): ApiSpec {\n const schemas = this.readSchemas(root);\n const sections = this.readSections(root);\n return new ApiSpec(\n root.at('info').text('title') ?? 'API reference',\n root.at('info').text('version') ?? '',\n root.at('info').text('description') ?? '',\n this.readServers(root),\n sections,\n this.readSecuritySchemes(root),\n schemas,\n this.securityKeysIn(root),\n );\n }\n\n private readServers(root: JsonNode): readonly ServerInfo[] {\n return root\n .list('servers')\n .map(\n (entry: JsonNode): ServerInfo =>\n new ServerInfo(entry.text('url') ?? '', entry.text('description')),\n );\n }\n\n private readSecuritySchemes(root: JsonNode): readonly SecuritySchemeInfo[] {\n const declared = root.at('components').at('securitySchemes');\n return declared\n .entries()\n .map(\n (entry: JsonEntry): SecuritySchemeInfo =>\n new SecuritySchemeInfo(\n entry.key,\n entry.value.text('type') ?? '',\n entry.value.text('in') ?? '',\n entry.value.text('name') ?? '',\n entry.value.text('description'),\n ),\n );\n }\n\n private readSchemas(root: JsonNode): readonly NamedSchema[] {\n const slugs = new Slug();\n return root\n .at('components')\n .at('schemas')\n .entries()\n .map(\n (entry: JsonEntry): NamedSchema =>\n new NamedSchema(\n entry.key,\n slugs.unique(entry.key),\n entry.value,\n this.shape.hasOwnPage(entry.value),\n ),\n );\n }\n\n private readSections(root: JsonNode): readonly TagSection[] {\n const slugs = new Slug();\n const operations = this.readOperations(root, slugs);\n const webhooks = this.readWebhooks(root, slugs);\n const order = this.sectionOrder(root, operations, webhooks);\n const sections: TagSection[] = [];\n for (const tag of order) {\n const inTag = operations.filter((one: OperationInfo): boolean => one.tag === tag);\n const eventsInTag = webhooks.filter((one: OperationInfo): boolean => one.tag === tag);\n sections.push(\n new TagSection(tag, this.tagDescription(root, tag), [...inTag, ...eventsInTag]),\n );\n }\n return sections;\n }\n\n /** `tags[]` first, in its published order, then any tag only an operation mentions. */\n private sectionOrder(\n root: JsonNode,\n operations: readonly OperationInfo[],\n webhooks: readonly OperationInfo[],\n ): readonly string[] {\n const order: string[] = [];\n for (const declared of root.list('tags')) {\n const name = declared.text('name');\n if (name !== undefined && !order.includes(name)) {\n order.push(name);\n }\n }\n for (const one of [...operations, ...webhooks]) {\n if (!order.includes(one.tag)) {\n order.push(one.tag);\n }\n }\n return order.filter((tag: string): boolean =>\n [...operations, ...webhooks].some((one: OperationInfo): boolean => one.tag === tag),\n );\n }\n\n private tagDescription(root: JsonNode, tag: string): string {\n for (const declared of root.list('tags')) {\n if (declared.text('name') === tag) {\n return declared.text('description') ?? '';\n }\n }\n return '';\n }\n\n private readOperations(root: JsonNode, slugs: Slug): readonly OperationInfo[] {\n const found: OperationInfo[] = [];\n for (const pathEntry of root.at('paths').entries()) {\n for (const methodEntry of pathEntry.value.entries()) {\n if (!HTTP_METHODS.includes(methodEntry.key)) {\n continue;\n }\n found.push(\n this.readOperation(\n root,\n methodEntry.value,\n slugs,\n methodEntry.key.toUpperCase(),\n pathEntry.key,\n false,\n ),\n );\n }\n }\n return found;\n }\n\n private readWebhooks(root: JsonNode, slugs: Slug): readonly OperationInfo[] {\n const found: OperationInfo[] = [];\n for (const eventEntry of root.at('webhooks').entries()) {\n for (const methodEntry of eventEntry.value.entries()) {\n if (!HTTP_METHODS.includes(methodEntry.key)) {\n continue;\n }\n found.push(\n this.readOperation(root, methodEntry.value, slugs, '', eventEntry.key, true),\n );\n }\n }\n return found;\n }\n\n private readOperation(\n root: JsonNode,\n node: JsonNode,\n slugs: Slug,\n httpMethod: string,\n pathOrEvent: string,\n isWebhook: boolean,\n ): OperationInfo {\n const name = node.text('summary') ?? node.text('operationId') ?? pathOrEvent;\n return new OperationInfo(\n name,\n slugs.unique(name),\n httpMethod,\n isWebhook ? '' : pathOrEvent,\n node.text('description') ?? '',\n this.tagOf(node),\n this.requestSchemaOf(node),\n this.responsesOf(node),\n isWebhook,\n isWebhook ? [] : this.operationSecurityKeys(root, node),\n isWebhook ? pathOrEvent : '',\n );\n }\n\n private tagOf(node: JsonNode): string {\n for (const tag of node.list('tags')) {\n const name = tag.asText();\n if (name !== undefined) {\n return name;\n }\n }\n return UNTAGGED_SECTION;\n }\n\n private requestSchemaOf(node: JsonNode): JsonNode | undefined {\n const schema = node.at('requestBody').at('content').at('application/json').at('schema');\n return schema.isObject() ? schema : undefined;\n }\n\n private responsesOf(node: JsonNode): readonly ResponseInfo[] {\n return node\n .at('responses')\n .entries()\n .map((entry: JsonEntry): ResponseInfo => {\n const schema = entry.value.at('content').at('application/json').at('schema');\n return new ResponseInfo(\n entry.key,\n entry.value.text('description') ?? '',\n schema.isObject() ? schema : undefined,\n );\n });\n }\n\n /**\n * The credentials this operation needs: its own `security` when it states one, the document's\n * otherwise. An operation stating `security: []` needs none, and that empty array is the\n * OpenAPI spelling of \"no credential\" rather than of \"inherit\" — so it must not fall back.\n */\n private operationSecurityKeys(root: JsonNode, node: JsonNode): readonly string[] {\n if (Array.isArray(node.at('security').raw)) {\n return this.securityKeysIn(node);\n }\n return this.securityKeysIn(root);\n }\n\n private securityKeysIn(holder: JsonNode): readonly string[] {\n const keys: string[] = [];\n for (const requirement of holder.list('security')) {\n for (const key of requirement.keys()) {\n if (!keys.includes(key)) {\n keys.push(key);\n }\n }\n }\n return keys;\n }\n}\n"]}