@aurodesignsystem/auro-library 5.14.0 → 5.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/bin/generateDocs.mjs +4 -210
  3. package/bin/generateDocs_index.mjs +4 -210
  4. package/dist/_chunks/chunk-2MOEVVSZ.mjs +308 -0
  5. package/dist/_chunks/chunk-H7YO7ERJ.mjs +69 -0
  6. package/dist/_chunks/chunk-JLCAYVRX.mjs +84 -0
  7. package/dist/_chunks/chunk-RKBXVLA5.mjs +5983 -0
  8. package/dist/_chunks/chunk-TDFKN2EP.mjs +38 -0
  9. package/dist/_chunks/chunk-UY4SIQT6.mjs +201 -0
  10. package/dist/_chunks/chunk-V7YBXHAI.mjs +32379 -0
  11. package/dist/bin/generateDocs.mjs +152 -0
  12. package/dist/bin/generateDocs_index.mjs +152 -0
  13. package/dist/build/generateDocs.mjs +18 -0
  14. package/dist/build/generateReadme.mjs +49 -0
  15. package/dist/build/generateWcaComponent.mjs +6657 -0
  16. package/dist/build/processors/defaultDocsProcessor.mjs +16 -0
  17. package/dist/build/processors/defaultDotGithubSync.mjs +12 -0
  18. package/dist/build/syncGithubFiles.mjs +18 -0
  19. package/dist/utils/auroTemplateFiller.mjs +8 -0
  20. package/dist/utils/sharedFileProcessorUtils.mjs +31 -0
  21. package/package.json +10 -5
  22. package/scripts/build/generateDocs.mjs +4 -24
  23. package/scripts/build/generateReadme.mjs +4 -60
  24. package/scripts/build/generateWcaComponent.mjs +4 -43
  25. package/scripts/build/postinstall.mjs +10 -10
  26. package/scripts/build/pre-commit.mjs +13 -7
  27. package/scripts/build/processors/defaultDocsProcessor.mjs +4 -83
  28. package/scripts/build/processors/defaultDotGithubSync.mjs +4 -83
  29. package/scripts/build/syncGithubFiles.mjs +4 -25
  30. package/scripts/runtime/floatingUI.mjs +2 -1
  31. package/scripts/runtime/generateUUID/generateUUID.mjs +41 -0
  32. package/scripts/runtime/generateUUID/index.mjs +1 -0
  33. package/scripts/utils/ansiColors.mjs +119 -0
  34. package/scripts/utils/auroLibraryUtils.mjs +87 -51
  35. package/scripts/utils/auroTemplateFiller.mjs +4 -178
  36. package/scripts/utils/logger.mjs +27 -16
  37. package/scripts/utils/sharedFileProcessorUtils.mjs +4 -270
  38. package/scripts/build/deprecatedProseToFieldPlugin.spec.js +0 -188
  39. package/scripts/runtime/ClickTracker/test/ClickTracker.test.js +0 -424
  40. package/scripts/runtime/FocusTrap/test/FocusTrap.test.js +0 -168
  41. package/scripts/runtime/Focusables/test/Focusables.test.js +0 -185
  42. package/scripts/runtime/dateUtilities/dateFormatter.test.js +0 -284
  43. package/scripts/runtime/dateUtilities/dateUtilities.test.js +0 -80
  44. package/scripts/runtime/floatingUI/test/floatingUI.test.js +0 -189
  45. package/scripts/runtime/floatingUI.test.js +0 -478
@@ -1,270 +1,4 @@
1
- import * as mdMagic from 'markdown-magic';
2
- import fs from 'node:fs/promises';
3
- import path from "node:path";
4
-
5
- import AuroLibraryUtils from "./auroLibraryUtils.mjs";
6
- import { AuroTemplateFiller } from "./auroTemplateFiller.mjs";
7
- import { AuroFileHandler } from "./auroFileHandler.mjs";
8
- import {Logger} from "./logger.mjs";
9
-
10
-
11
- // This JSDoc type trickery is here so you get "decent enough" auto complete
12
- /** @type {typeof import('markdown-magic').markdownMagic} */
13
- const applyMarkdownMagic = mdMagic.default
14
-
15
- /**
16
- * Optional output configuration
17
- * @typedef {object} OutputConfig
18
- * @property {string} [directory] - Change output path of new content. Default behavior is replacing the original file
19
- * @property {boolean} [removeComments = false] - Remove comments from output. Default is false.
20
- * @property {function} [pathFormatter] - Custom function for altering output paths
21
- * @property {boolean} [applyTransformsToSource = false] - Apply transforms to source file. Default is true. This is for when outputDir is set.
22
- */
23
-
24
- /**
25
- * Configuration for Markdown magic
26
- *
27
- * Below is the main config for `markdown-magic` - copy-pasted directly from the library
28
- *
29
- * @typedef {object} MarkdownMagicOptions
30
- * @property {string} matchWord - [v2-only] string to match for variables
31
- * @property {FilePathsOrGlobs} [files] - Files to process.
32
- * @property {Array} [transforms = defaultTransforms] - Custom commands to transform block contents, see transforms & custom transforms sections below.
33
- * @property {OutputConfig} [output] - Output configuration
34
- * @property {SyntaxType} [syntax = 'md'] - Syntax to parse
35
- * @property {string} [open = 'doc-gen'] - Opening match word
36
- * @property {string} [close = 'end-doc-gen'] - Closing match word. If not defined will be same as opening word.
37
- * @property {string} [cwd = process.cwd() ] - Current working directory. Default process.cwd()
38
- * @property {boolean} [outputFlatten] - Flatten files that are output
39
- * @property {boolean} [useGitGlob] - Use git glob for LARGE file directories
40
- * @property {boolean} [dryRun = false] - See planned execution of matched blocks
41
- * @property {boolean} [debug = false] - See debug details
42
- * @property {boolean} [silent = false] - Silence all console output
43
- * @property {boolean} [applyTransformsToSource = true] - Apply transforms to source file. Default is true.
44
- * @property {boolean} [failOnMissingTransforms = false] - Fail if transform functions are missing. Default skip blocks.
45
- * @property {boolean} [failOnMissingRemote = true] - Fail if remote file is missing.
46
- */
47
-
48
-
49
- // Config
50
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
51
-
52
- /** @type {MarkdownMagicOptions} */
53
- export const MD_MAGIC_CONFIG = {
54
- matchWord: "AURO-GENERATED-CONTENT",
55
- output: {
56
- directory: "./",
57
- applyTransformsToSource: true
58
- }
59
- };
60
-
61
- // Initialize utility services
62
- export const auroLibraryUtils = new AuroLibraryUtils();
63
- export const templateFiller = new AuroTemplateFiller();
64
-
65
- // List of components that do not support ESM to determine which README to use
66
- export const nonEsmComponents = ['combobox', 'datepicker', 'menu', 'pane', 'select'];
67
-
68
-
69
- // Local utils
70
- /**
71
- *
72
- * @param {string} pathLike - Please include the preceding slash! Like so: `/docTemplates/README.md`
73
- * @return {string}
74
- */
75
- // TODO: test this in auro-flight before merging to main
76
- export function fromAuroComponentRoot(pathLike) {
77
- if (pathLike.startsWith('/')) {
78
- // remove the first slash
79
- return path.join(auroLibraryUtils.getProjectRootPath, pathLike.slice(1))
80
- }
81
-
82
- return path.join(auroLibraryUtils.getProjectRootPath, pathLike)
83
- }
84
-
85
-
86
- // External assets
87
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88
-
89
- /**
90
- * Generate a URL for the WC Generator README file.
91
- * @param {string} branchOrTag
92
- * @param {string} fileNameWithPath
93
- * @return {string}
94
- */
95
- export function generateWCGeneratorUrl(branchOrTag, fileNameWithPath) {
96
- const baseRepoUrl = 'https://raw.githubusercontent.com/AlaskaAirlines/WC-Generator'
97
-
98
- // check if tag starts with 'vX' since our tags are `v4.0.0`
99
- const isTag = branchOrTag.startsWith('v') &&
100
- /^\d+\.\d+\.\d+(-.*)?$/.test(branchOrTag.slice(1));
101
-
102
- if (isTag) {
103
- return `${baseRepoUrl}/refs/tags/${branchOrTag}/${fileNameWithPath}`;
104
- }
105
-
106
- if (branchOrTag !== 'master') {
107
- return `${baseRepoUrl}/refs/heads/${branchOrTag}/${fileNameWithPath}`;
108
- }
109
-
110
- return `${baseRepoUrl}/master/${fileNameWithPath}`;
111
- }
112
-
113
- /**
114
- * @param {string} branchOrTag - the git branch or tag to use for the README source
115
- * @param {string} [variantOverride] - override the variant string
116
- * @return {string}
117
- */
118
- export function generateReadmeUrl(branchOrTag = 'master', variantOverride = '') {
119
- // LEGACY CODE FOR NON-ESM COMPONENTS
120
-
121
- const nameExtractionData = templateFiller.values;
122
- let variantString = '';
123
-
124
- if (!nonEsmComponents.includes(nameExtractionData.name)) {
125
- variantString = '_esm';
126
- }
127
-
128
- // END LEGACY CODE
129
-
130
- if (variantOverride !== '') {
131
- variantString = variantOverride;
132
- }
133
-
134
- return generateWCGeneratorUrl(branchOrTag, `componentDocs/README${variantString}.md`);
135
- }
136
-
137
- // Main Markdown magic processors
138
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139
-
140
- /**
141
- * This is the expected object type when passing something other than a string.
142
- * @typedef {Object} InputFileType
143
- * @property {string} remoteUrl - The remote template to fetch
144
- * @property {string} fileName - Path including file name to store
145
- * @property {boolean} [overwrite] - Default is true. Choose to overwrite the file if it exists
146
- */
147
-
148
-
149
- /**
150
- * @typedef {Object} FileProcessorConfig
151
- * @property {string} identifier - A unique identifier for this file (used for logging).
152
- * @property {string | InputFileType} input - path to an input file, including filename
153
- * @property {string} output - path to an output file, including filename
154
- * @property {Partial<MarkdownMagicOptions>} [mdMagicConfig] - extra configuration options for md magic
155
- * @property {Array<(contents: string) => string>} [preProcessors] - extra processor functions to run on content AFTER markdownmagic and BEFORE templateFiller
156
- * @property {Array<(contents: string) => string>} [postProcessors] - extra processor functions to run on content
157
- * @property {object} [extraVars] - extra variables to use in the template
158
- */
159
-
160
-
161
- // Individual file processing steps
162
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
163
-
164
- /**
165
- * Retrieve a remote file using a provided configuration and store at a local path.
166
- * @param {InputFileType} input - the input file configuration
167
- * @return {Promise<void>}
168
- */
169
- export async function retrieveRemoteFileCopy(input) {
170
- const bareFileName = input.fileName
171
-
172
- Logger.log(`Retrieving latest "${bareFileName}" file...`);
173
-
174
- // 0b. Attempt to populate from remote file
175
- const contents = await fetch(input.remoteUrl, {
176
- redirect: 'follow'
177
- }).then(r => r.text());
178
-
179
- // 0c. Write remote contents to local folder as cache
180
- await AuroFileHandler.tryWriteFile(input.fileName, contents);
181
- }
182
-
183
-
184
- /**
185
- * Run markdown magic on a file.
186
- * @param {string} input
187
- * @param {string} output
188
- * @param {Partial<MarkdownMagicOptions>} [extraMdMagicConfig] - extra configuration options for md magic
189
- * @return {Promise<void>}
190
- */
191
- export async function runMarkdownMagicOnFile(input, output, extraMdMagicConfig = {}) {
192
- await applyMarkdownMagic(output, {
193
- ...MD_MAGIC_CONFIG,
194
- ...extraMdMagicConfig
195
- });
196
- }
197
-
198
-
199
- /**
200
- * Optionally copy a file to a new location.
201
- * @param {string} input - the input file path
202
- * @param {string} output - the output file path
203
- * @param {boolean} overwrite - whether to overwrite the file if it exists (default is true)
204
- * @return {Promise<void>}
205
- */
206
- export async function optionallyCopyFile(input, output, overwrite = true) {
207
- if (await AuroFileHandler.exists(output) && !overwrite) {
208
- return;
209
- }
210
-
211
- if (!await AuroFileHandler.tryCopyFile(input, output)) {
212
- throw new Error(`Error copying "${input}" file to output ${output}`);
213
- }
214
- }
215
-
216
- /**
217
- * Process the content of a file.
218
- *
219
- * This is a high level function that performs the following via lower functions:
220
- * - Read contents of file
221
- * - Run "markdown-magic" on file contents (optional, *.md specific)
222
- * - Run template variable replacement on file contents
223
- * @param {FileProcessorConfig} config - the config for this file
224
- */
225
- export async function processContentForFile(config) {
226
- const { input: rawInput, output, mdMagicConfig, extraVars = {} } = config
227
-
228
- // Helper vars
229
- const derivedInputPath = typeof rawInput === 'string' ? rawInput : rawInput.fileName;
230
- const segments = derivedInputPath.split("/")
231
- const bareFileName = segments[segments.length - 1]
232
-
233
- // 0. Optionally retrieve a remote file
234
- if (typeof rawInput === 'object') {
235
- await retrieveRemoteFileCopy(rawInput);
236
- }
237
-
238
- // 1. Copy input or local input cache to output
239
- await optionallyCopyFile(derivedInputPath, output, rawInput.overwrite ?? true);
240
-
241
- // 2. If the file is a Markdown file, run markdown magic to inject contents and perform replacements
242
- if (output.endsWith(".md")) {
243
- await runMarkdownMagicOnFile(derivedInputPath, output, mdMagicConfig);
244
- }
245
-
246
- // 3a. Read the output file contents
247
- let fileContents = await fs.readFile(output, {encoding: 'utf-8'});
248
-
249
- // 3b. Run any pre-processors
250
- if (config.preProcessors) {
251
- for (const processor of config.preProcessors) {
252
- fileContents = processor(fileContents)
253
- }
254
- }
255
-
256
- // 3c. Replace template variables in output file
257
- fileContents = templateFiller.replaceTemplateValues(fileContents, extraVars);
258
-
259
- // 3d. Run any post-processors
260
- if (config.postProcessors) {
261
- for (const processor of config.postProcessors) {
262
- fileContents = processor(fileContents)
263
- }
264
- }
265
-
266
- // 3e. Write the final file contents
267
- if (!await AuroFileHandler.tryWriteFile(output, fileContents)) {
268
- throw new Error(`Error writing "${bareFileName}" file to output ${output}`);
269
- }
270
- }
1
+ // Shim for the pre-compiled build. Do not edit.
2
+ // Generated by build/bundleDocsScripts.mjs from src/utils/sharedFileProcessorUtils.mjs.
3
+ // Edit that file, then run `npm run build:bundles`.
4
+ export * from "../../dist/utils/sharedFileProcessorUtils.mjs";
@@ -1,188 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { deprecatedProseToFieldPlugin } from "./deprecatedProseToFieldPlugin.mjs";
3
-
4
- /**
5
- * Wrap one or more `entries` (events or slots) in a minimal Custom Elements
6
- * Manifest shape, run the plugin's `packageLinkPhase` over it, and return the
7
- * mutated entries so assertions can read their `deprecated` field.
8
- */
9
- const run = (kind, entries) => {
10
- const manifest = {
11
- modules: [
12
- {
13
- declarations: [{ [kind]: entries }],
14
- },
15
- ],
16
- };
17
- deprecatedProseToFieldPlugin().packageLinkPhase({
18
- customElementsManifest: manifest,
19
- });
20
- return manifest.modules[0].declarations[0][kind];
21
- };
22
-
23
- describe("deprecatedProseToFieldPlugin", () => {
24
- it("has the expected plugin name", () => {
25
- expect(deprecatedProseToFieldPlugin().name).toBe(
26
- "deprecated-prose-to-field",
27
- );
28
- });
29
-
30
- describe("marker + guidance -> string message", () => {
31
- it('extracts guidance following a "(deprecated) -" marker', () => {
32
- const [entry] = run("events", [
33
- {
34
- name: "change",
35
- description: "(Deprecated) - Use the `input` event instead.",
36
- },
37
- ]);
38
- expect(entry.deprecated).toBe("Use the `input` event instead.");
39
- });
40
-
41
- it("extracts guidance for each supported separator (- : – —)", () => {
42
- const separators = ["-", ":", "–", "—"];
43
- separators.forEach((sep) => {
44
- const [entry] = run("events", [
45
- {
46
- name: "change",
47
- description: `**DEPRECATED** ${sep} Use \`input\` instead.`,
48
- },
49
- ]);
50
- expect(entry.deprecated).toBe("Use `input` instead.");
51
- });
52
- });
53
-
54
- it("trims surrounding whitespace from the guidance text", () => {
55
- const [entry] = run("slots", [
56
- {
57
- name: "legacy",
58
- description: "deprecated: Use the `default` slot instead. ",
59
- },
60
- ]);
61
- expect(entry.deprecated).toBe("Use the `default` slot instead.");
62
- });
63
- });
64
-
65
- describe("marker with no guidance -> boolean true", () => {
66
- it('flags a "**DEPRECATED**" prose with no replacement guidance', () => {
67
- const [entry] = run("slots", [
68
- { name: "legacy", description: "**DEPRECATED** legacy slot" },
69
- ]);
70
- expect(entry.deprecated).toBe(true);
71
- });
72
-
73
- it('flags a bare "(deprecated)" marker as true', () => {
74
- const [entry] = run("events", [
75
- { name: "change", description: "(deprecated)" },
76
- ]);
77
- expect(entry.deprecated).toBe(true);
78
- });
79
- });
80
-
81
- describe("non-deprecated entries are untouched", () => {
82
- it("does not add a deprecated field when no marker is present", () => {
83
- const [entry] = run("events", [
84
- { name: "input", description: "Fires when the value changes." },
85
- ]);
86
- expect(entry).not.toHaveProperty("deprecated");
87
- });
88
-
89
- it('does not match unrelated words containing "deprecated" as a substring', () => {
90
- const [entry] = run("events", [
91
- { name: "input", description: "This is undeprecated behavior." },
92
- ]);
93
- expect(entry).not.toHaveProperty("deprecated");
94
- });
95
- });
96
-
97
- describe("pre-existing deprecated values are preserved", () => {
98
- it("does not overwrite an already-set string message", () => {
99
- const [entry] = run("events", [
100
- {
101
- name: "change",
102
- description: "(Deprecated) - Use `input`.",
103
- deprecated: "existing guidance",
104
- },
105
- ]);
106
- expect(entry.deprecated).toBe("existing guidance");
107
- });
108
-
109
- it("does not overwrite an already-set boolean false", () => {
110
- const [entry] = run("events", [
111
- {
112
- name: "change",
113
- description: "(Deprecated) - Use `input`.",
114
- deprecated: false,
115
- },
116
- ]);
117
- expect(entry.deprecated).toBe(false);
118
- });
119
- });
120
-
121
- describe("malformed / missing descriptions are skipped safely", () => {
122
- it("skips entries whose description is not a string", () => {
123
- const [noDesc, objDesc] = run("slots", [
124
- { name: "a" },
125
- { name: "b", description: { text: "deprecated" } },
126
- ]);
127
- expect(noDesc).not.toHaveProperty("deprecated");
128
- expect(objDesc).not.toHaveProperty("deprecated");
129
- });
130
- });
131
-
132
- describe("applies to both events and slots, leaves other fields alone", () => {
133
- it("promotes both events and slots on the same declaration", () => {
134
- const manifest = {
135
- modules: [
136
- {
137
- declarations: [
138
- {
139
- events: [
140
- { name: "change", description: "deprecated - Use `input`." },
141
- ],
142
- slots: [
143
- { name: "legacy", description: "(Deprecated) legacy slot" },
144
- ],
145
- attributes: [
146
- {
147
- name: "value",
148
- description: "deprecated - do not touch me",
149
- },
150
- ],
151
- members: [
152
- { name: "reset", description: "(deprecated) leave me alone" },
153
- ],
154
- },
155
- ],
156
- },
157
- ],
158
- };
159
- deprecatedProseToFieldPlugin().packageLinkPhase({
160
- customElementsManifest: manifest,
161
- });
162
- const [decl] = manifest.modules[0].declarations;
163
- expect(decl.events[0].deprecated).toBe("Use `input`.");
164
- expect(decl.slots[0].deprecated).toBe(true);
165
- expect(decl.attributes[0]).not.toHaveProperty("deprecated");
166
- expect(decl.members[0]).not.toHaveProperty("deprecated");
167
- });
168
- });
169
-
170
- describe("does not throw on empty or absent manifest structures", () => {
171
- it("handles a manifest with no modules", () => {
172
- expect(() =>
173
- deprecatedProseToFieldPlugin().packageLinkPhase({
174
- customElementsManifest: {},
175
- }),
176
- ).not.toThrow();
177
- });
178
-
179
- it("handles declarations without events or slots arrays", () => {
180
- const manifest = { modules: [{ declarations: [{}] }] };
181
- expect(() =>
182
- deprecatedProseToFieldPlugin().packageLinkPhase({
183
- customElementsManifest: manifest,
184
- }),
185
- ).not.toThrow();
186
- });
187
- });
188
- });