@astryxdesign/cli 0.6.3-canary.e073c9f → 0.6.3-canary.e7819e0
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.
- package/api/integration/validate-integration.test.mjs +91 -0
- package/assets/templates/pages/table-tree/page.tsx +1704 -0
- package/assets/templates/pages/table-tree/template.doc.mjs +12 -0
- package/foundation/fs/path-safety.d.mts +3 -2
- package/foundation/fs/path-safety.mjs +49 -19
- package/foundation/fs/path-safety.test.mjs +50 -0
- package/package.json +9 -9
|
@@ -13,10 +13,16 @@ import {afterEach, beforeEach, describe, expect, it} from 'vitest';
|
|
|
13
13
|
import * as fs from 'node:fs';
|
|
14
14
|
import * as path from 'node:path';
|
|
15
15
|
import {
|
|
16
|
+
validateIntegration,
|
|
16
17
|
validateLocalIntegration,
|
|
17
18
|
validateInstalledIntegration,
|
|
18
19
|
summarizeIssues,
|
|
19
20
|
} from './validate-integration.mjs';
|
|
21
|
+
import {
|
|
22
|
+
integrationComponentConflicts,
|
|
23
|
+
integrationDocConflicts,
|
|
24
|
+
integrationTemplateConflicts,
|
|
25
|
+
} from './authoring-checks.mjs';
|
|
20
26
|
|
|
21
27
|
let tmpDir;
|
|
22
28
|
|
|
@@ -472,3 +478,88 @@ describe('validate-integration API', () => {
|
|
|
472
478
|
expect(byCode(result.issues, 'invalid_package_spec')).toHaveLength(1);
|
|
473
479
|
});
|
|
474
480
|
});
|
|
481
|
+
|
|
482
|
+
describe('integration diagnostics are read-only', () => {
|
|
483
|
+
/** Every directory and file under `dir`, with file bytes. */
|
|
484
|
+
function snapshot(dir) {
|
|
485
|
+
/** @type {Record<string, string>} */
|
|
486
|
+
const entries = {};
|
|
487
|
+
/** @param {string} current */
|
|
488
|
+
const walk = current => {
|
|
489
|
+
for (const entry of fs.readdirSync(current, {withFileTypes: true})) {
|
|
490
|
+
const full = path.join(current, entry.name);
|
|
491
|
+
const key = path.relative(dir, full);
|
|
492
|
+
if (entry.isDirectory()) {
|
|
493
|
+
entries[`${key}/`] = '';
|
|
494
|
+
walk(full);
|
|
495
|
+
} else {
|
|
496
|
+
entries[key] = fs.readFileSync(full, 'base64');
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
walk(dir);
|
|
501
|
+
return entries;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/** A package with valid, broken, conflicting, and unreachable contributions. */
|
|
505
|
+
function writeDiagnosedPackage(dir) {
|
|
506
|
+
writePackage(dir, {
|
|
507
|
+
manifest:
|
|
508
|
+
"export default {\n components: './components',\n templates: './templates',\n docs: './docs',\n codemods: './gone',\n themes: './themes',\n};\n",
|
|
509
|
+
});
|
|
510
|
+
const write = (relative, contents) => {
|
|
511
|
+
fs.mkdirSync(path.dirname(path.join(dir, relative)), {recursive: true});
|
|
512
|
+
fs.writeFileSync(path.join(dir, relative), contents);
|
|
513
|
+
};
|
|
514
|
+
write(
|
|
515
|
+
'components/Card.doc.mjs',
|
|
516
|
+
"export default {type: 'component', name: 'Card', props: []};\n",
|
|
517
|
+
);
|
|
518
|
+
write('components/Card.tsx', 'export function Card() { return null; }\n');
|
|
519
|
+
write(
|
|
520
|
+
'components/Orphan.doc.mjs',
|
|
521
|
+
"export default {type: 'component', name: 'Orphan', props: []};\n",
|
|
522
|
+
);
|
|
523
|
+
write('templates/dash.doc.mjs', "export default {type: 'page', name: 'Dash'};\n");
|
|
524
|
+
write(
|
|
525
|
+
'docs/theme.doc.mjs',
|
|
526
|
+
"export default {type: 'generic', name: 'theme', title: 'Theme', description: 'x', sections: [{title: 'A', content: [{type: 'prose', text: 'x'}]}]};\n",
|
|
527
|
+
);
|
|
528
|
+
write('themes/manifest.json', '{"version": 1, "themes": [{"slug": 7}]}\n');
|
|
529
|
+
write(
|
|
530
|
+
'stray/Stray.doc.mjs',
|
|
531
|
+
"export default {type: 'component', name: 'Stray', props: []};\n",
|
|
532
|
+
);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
it('leaves local and installed packages byte-for-byte unchanged', async () => {
|
|
536
|
+
const pkgDir = path.join(tmpDir, 'pkg');
|
|
537
|
+
writeDiagnosedPackage(pkgDir);
|
|
538
|
+
const consumer = path.join(tmpDir, 'consumer');
|
|
539
|
+
fs.mkdirSync(consumer, {recursive: true});
|
|
540
|
+
fs.writeFileSync(
|
|
541
|
+
path.join(consumer, 'package.json'),
|
|
542
|
+
JSON.stringify({name: 'consumer'}),
|
|
543
|
+
);
|
|
544
|
+
writeDiagnosedPackage(path.join(consumer, 'node_modules', '@acme', 'widgets'));
|
|
545
|
+
const before = {pkg: snapshot(pkgDir), consumer: snapshot(consumer)};
|
|
546
|
+
|
|
547
|
+
const local = await validateIntegration(undefined, {cwd: pkgDir});
|
|
548
|
+
const installed = await validateIntegration('@acme/widgets', {
|
|
549
|
+
cwd: consumer,
|
|
550
|
+
});
|
|
551
|
+
for (const [pkg, cwd] of [
|
|
552
|
+
[undefined, pkgDir],
|
|
553
|
+
['@acme/widgets', consumer],
|
|
554
|
+
]) {
|
|
555
|
+
await integrationTemplateConflicts(pkg, {cwd});
|
|
556
|
+
await integrationComponentConflicts(pkg, {cwd});
|
|
557
|
+
await integrationDocConflicts(pkg, {cwd});
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
expect(summarizeIssues(local.data.issues).errors).toBeGreaterThan(0);
|
|
561
|
+
expect(byCode(local.data.issues, 'unreachable_contribution')).toHaveLength(1);
|
|
562
|
+
expect(summarizeIssues(installed.data.issues).errors).toBeGreaterThan(0);
|
|
563
|
+
expect({pkg: snapshot(pkgDir), consumer: snapshot(consumer)}).toEqual(before);
|
|
564
|
+
});
|
|
565
|
+
});
|