@modularcore/registry 0.2.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.
- package/dist/build-registry.d.ts +19 -0
- package/dist/build-registry.d.ts.map +1 -0
- package/dist/build-registry.js +166 -0
- package/dist/build-registry.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/resolve-write.d.ts +17 -0
- package/dist/resolve-write.d.ts.map +1 -0
- package/dist/resolve-write.js +40 -0
- package/dist/resolve-write.js.map +1 -0
- package/dist/schema.d.ts +58 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +6 -0
- package/dist/schema.js.map +1 -0
- package/dist/schema.zod.d.ts +118 -0
- package/dist/schema.zod.d.ts.map +1 -0
- package/dist/schema.zod.js +70 -0
- package/dist/schema.zod.js.map +1 -0
- package/dist/tarball.d.ts +8 -0
- package/dist/tarball.d.ts.map +1 -0
- package/dist/tarball.js +28 -0
- package/dist/tarball.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { RegistryIndexEntry } from './schema.js';
|
|
2
|
+
export interface BuildRegistryOptions {
|
|
3
|
+
packagesRoot: string;
|
|
4
|
+
outputDir: string;
|
|
5
|
+
}
|
|
6
|
+
export interface BuildRegistrySummary {
|
|
7
|
+
outputDir: string;
|
|
8
|
+
publicIndex: RegistryIndexEntry[];
|
|
9
|
+
componentNames: string[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Scans `packages/*\/modularcore.json`, validates each descriptor, reads its `files[]`
|
|
13
|
+
* content, and emits `index.json` + `{name}.json` + `{name}.tar.gz` per component.
|
|
14
|
+
* `internal` components are built (so the local spike can read them) but excluded from
|
|
15
|
+
* `index.json` (FMA2). Output is staged in a temp dir and moved into place with a single
|
|
16
|
+
* `rename` (FMA6) so partial builds are never visible at `outputDir`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildRegistry({ packagesRoot, outputDir, }: BuildRegistryOptions): Promise<BuildRegistrySummary>;
|
|
19
|
+
//# sourceMappingURL=build-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-registry.d.ts","sourceRoot":"","sources":["../src/build-registry.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAA0C,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE9F,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAyHD;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,EAClC,YAAY,EACZ,SAAS,GACV,EAAE,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAoDtD"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, writeFile, } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join, resolve, sep } from 'node:path';
|
|
4
|
+
import { registryDescriptorSchema } from './schema.zod.js';
|
|
5
|
+
import { buildTarball } from './tarball.js';
|
|
6
|
+
async function findComponentDirs(packagesRoot) {
|
|
7
|
+
const entries = await readdir(packagesRoot, { withFileTypes: true });
|
|
8
|
+
const dirs = [];
|
|
9
|
+
for (const entry of entries) {
|
|
10
|
+
if (!entry.isDirectory())
|
|
11
|
+
continue;
|
|
12
|
+
const descriptorPath = join(packagesRoot, entry.name, 'modularcore.json');
|
|
13
|
+
try {
|
|
14
|
+
await stat(descriptorPath);
|
|
15
|
+
dirs.push(join(packagesRoot, entry.name));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// No descriptor in this package: it is a plain package, not a registry component.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return dirs;
|
|
22
|
+
}
|
|
23
|
+
async function loadDescriptor(componentDir) {
|
|
24
|
+
const descriptorPath = join(componentDir, 'modularcore.json');
|
|
25
|
+
const raw = await readFile(descriptorPath, 'utf8');
|
|
26
|
+
let json;
|
|
27
|
+
try {
|
|
28
|
+
json = JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`Invalid JSON in ${descriptorPath}: ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
const parsed = registryDescriptorSchema.safeParse(json);
|
|
34
|
+
if (!parsed.success) {
|
|
35
|
+
throw new Error(`Invalid descriptor ${descriptorPath}: ${parsed.error.message}`);
|
|
36
|
+
}
|
|
37
|
+
return parsed.data;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* SA1: the zod schema already rejects ".." and absolute paths, but a symlink inside the
|
|
41
|
+
* package could still resolve outside it. This resolves the real path and re-asserts
|
|
42
|
+
* containment before any file content is read into the public registry output.
|
|
43
|
+
*/
|
|
44
|
+
async function assertSafeSourcePath(componentRealDir, filePath) {
|
|
45
|
+
const candidate = resolve(componentRealDir, filePath);
|
|
46
|
+
let real;
|
|
47
|
+
try {
|
|
48
|
+
real = await realpath(candidate);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
throw new Error(`File not found or unreadable: ${candidate} (${error.message})`);
|
|
52
|
+
}
|
|
53
|
+
const prefix = componentRealDir.endsWith(sep) ? componentRealDir : componentRealDir + sep;
|
|
54
|
+
if (real !== componentRealDir && !real.startsWith(prefix)) {
|
|
55
|
+
throw new Error(`Refusing to read outside package root: "${filePath}" escapes ${componentRealDir}`);
|
|
56
|
+
}
|
|
57
|
+
return real;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* AD3: `encoding` is author-declared, not trusted blindly. If a file is declared `utf8`
|
|
61
|
+
* but its bytes don't round-trip losslessly through UTF-8 (i.e. it's actually binary),
|
|
62
|
+
* `Buffer.toString('utf8')` would silently replace invalid sequences with U+FFFD instead
|
|
63
|
+
* of failing — corrupting the registry output without any build error. Detect that case
|
|
64
|
+
* and fail loud instead of guessing.
|
|
65
|
+
*/
|
|
66
|
+
function isValidUtf8(buffer) {
|
|
67
|
+
return buffer.equals(Buffer.from(buffer.toString('utf8'), 'utf8'));
|
|
68
|
+
}
|
|
69
|
+
async function readEntryFile(componentRealDir, file) {
|
|
70
|
+
const realFilePath = await assertSafeSourcePath(componentRealDir, file.path);
|
|
71
|
+
const buffer = await readFile(realFilePath);
|
|
72
|
+
if (file.encoding === 'utf8' && !isValidUtf8(buffer)) {
|
|
73
|
+
throw new Error(`File "${file.path}" is declared encoding:"utf8" but contains binary/invalid UTF-8 content. ` +
|
|
74
|
+
`Declare it as encoding:"base64" in modularcore.json instead.`);
|
|
75
|
+
}
|
|
76
|
+
const content = file.encoding === 'base64' ? buffer.toString('base64') : buffer.toString('utf8');
|
|
77
|
+
return { ...file, content };
|
|
78
|
+
}
|
|
79
|
+
async function buildEntry(descriptor, componentDir) {
|
|
80
|
+
const componentRealDir = await realpath(componentDir);
|
|
81
|
+
const files = [];
|
|
82
|
+
for (const file of descriptor.files) {
|
|
83
|
+
files.push(await readEntryFile(componentRealDir, file));
|
|
84
|
+
}
|
|
85
|
+
return { ...descriptor, files };
|
|
86
|
+
}
|
|
87
|
+
function toIndexEntry(descriptor) {
|
|
88
|
+
return {
|
|
89
|
+
name: descriptor.name,
|
|
90
|
+
title: descriptor.title,
|
|
91
|
+
category: descriptor.category,
|
|
92
|
+
version: descriptor.version,
|
|
93
|
+
frameworks: descriptor.frameworks,
|
|
94
|
+
description: descriptor.description,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* FMA6: cross-checks every emitted component (public AND internal — internal entries are
|
|
99
|
+
* still read locally by the inject spike / future CLI dev flows) has a non-empty
|
|
100
|
+
* `{name}.json` and `{name}.tar.gz`.
|
|
101
|
+
*/
|
|
102
|
+
async function validateBuildOutput(dir, componentNames) {
|
|
103
|
+
for (const name of componentNames) {
|
|
104
|
+
const jsonPath = join(dir, `${name}.json`);
|
|
105
|
+
const tarPath = join(dir, `${name}.tar.gz`);
|
|
106
|
+
const [jsonStat, tarStat] = await Promise.all([stat(jsonPath), stat(tarPath)]);
|
|
107
|
+
if (jsonStat.size === 0)
|
|
108
|
+
throw new Error(`Post-build validation failed: ${jsonPath} is empty`);
|
|
109
|
+
if (tarStat.size === 0)
|
|
110
|
+
throw new Error(`Post-build validation failed: ${tarPath} is empty`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Scans `packages/*\/modularcore.json`, validates each descriptor, reads its `files[]`
|
|
115
|
+
* content, and emits `index.json` + `{name}.json` + `{name}.tar.gz` per component.
|
|
116
|
+
* `internal` components are built (so the local spike can read them) but excluded from
|
|
117
|
+
* `index.json` (FMA2). Output is staged in a temp dir and moved into place with a single
|
|
118
|
+
* `rename` (FMA6) so partial builds are never visible at `outputDir`.
|
|
119
|
+
*/
|
|
120
|
+
export async function buildRegistry({ packagesRoot, outputDir, }) {
|
|
121
|
+
const componentDirs = await findComponentDirs(packagesRoot);
|
|
122
|
+
if (componentDirs.length === 0) {
|
|
123
|
+
throw new Error(`No components with modularcore.json found under ${packagesRoot}`);
|
|
124
|
+
}
|
|
125
|
+
const entries = [];
|
|
126
|
+
const seenNames = new Set();
|
|
127
|
+
for (const componentDir of componentDirs) {
|
|
128
|
+
const descriptor = await loadDescriptor(componentDir);
|
|
129
|
+
if (seenNames.has(descriptor.name)) {
|
|
130
|
+
throw new Error(`Duplicate component name "${descriptor.name}" across packages/*`);
|
|
131
|
+
}
|
|
132
|
+
seenNames.add(descriptor.name);
|
|
133
|
+
entries.push(await buildEntry(descriptor, componentDir));
|
|
134
|
+
}
|
|
135
|
+
// Stage on the same filesystem/volume as `outputDir` (not the OS tmpdir): the final
|
|
136
|
+
// `rename` must be an atomic same-device move, and cross-device renames (EXDEV) fail
|
|
137
|
+
// outright — a real risk here since the project can live on a different volume than /tmp.
|
|
138
|
+
const outputParent = dirname(outputDir);
|
|
139
|
+
await mkdir(outputParent, { recursive: true });
|
|
140
|
+
const tmpRoot = await mkdtemp(join(outputParent, `.modularcore-registry-${randomUUID()}-`));
|
|
141
|
+
try {
|
|
142
|
+
const publicIndex = [];
|
|
143
|
+
for (const entry of entries) {
|
|
144
|
+
await writeFile(join(tmpRoot, `${entry.name}.json`), JSON.stringify(entry, null, 2), 'utf8');
|
|
145
|
+
const tarball = await buildTarball(entry.files);
|
|
146
|
+
await writeFile(join(tmpRoot, `${entry.name}.tar.gz`), tarball);
|
|
147
|
+
if (entry.visibility === 'public') {
|
|
148
|
+
publicIndex.push(toIndexEntry(entry));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
await writeFile(join(tmpRoot, 'index.json'), JSON.stringify(publicIndex, null, 2), 'utf8');
|
|
152
|
+
await validateBuildOutput(tmpRoot, entries.map((entry) => entry.name));
|
|
153
|
+
await rm(outputDir, { recursive: true, force: true });
|
|
154
|
+
await rename(tmpRoot, outputDir);
|
|
155
|
+
return {
|
|
156
|
+
outputDir,
|
|
157
|
+
publicIndex,
|
|
158
|
+
componentNames: entries.map((entry) => entry.name),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
await rm(tmpRoot, { recursive: true, force: true });
|
|
163
|
+
throw error;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=build-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-registry.js","sourceRoot":"","sources":["../src/build-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type { ComponentType, EnvVariableDescriptor, FileEncoding, RegistryDescriptor, RegistryEntry, RegistryFileDescriptor, RegistryFileWithContent, RegistryIndexEntry, SupportedFramework, Visibility, } from './schema.js';
|
|
2
|
+
export { envVariableSchema, fileEncodingSchema, registryDescriptorSchema, registryEntrySchema, registryFileSchema, registryFileWithContentSchema, registryIndexEntrySchema, visibilitySchema, } from './schema.zod.js';
|
|
3
|
+
export type { RegistryDescriptorInput, RegistryDescriptorParsed } from './schema.zod.js';
|
|
4
|
+
export { buildRegistry } from './build-registry.js';
|
|
5
|
+
export type { BuildRegistryOptions, BuildRegistrySummary } from './build-registry.js';
|
|
6
|
+
export { buildTarball } from './tarball.js';
|
|
7
|
+
export { resolveWriteTargetPath, writeRegistryEntryFiles } from './resolve-write.js';
|
|
8
|
+
export type { WriteResult } from './resolve-write.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,GACX,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,6BAA6B,EAC7B,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAEzF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEtF,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACrF,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { envVariableSchema, fileEncodingSchema, registryDescriptorSchema, registryEntrySchema, registryFileSchema, registryFileWithContentSchema, registryIndexEntrySchema, visibilitySchema, } from './schema.zod.js';
|
|
2
|
+
export { buildRegistry } from './build-registry.js';
|
|
3
|
+
export { buildTarball } from './tarball.js';
|
|
4
|
+
export { resolveWriteTargetPath, writeRegistryEntryFiles } from './resolve-write.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,6BAA6B,EAC7B,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RegistryEntry } from './schema.js';
|
|
2
|
+
export interface WriteResult {
|
|
3
|
+
target: string;
|
|
4
|
+
bytesWritten: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Shared by the spike injector (`scripts/inject-spike.mjs`) and the future CLI (Phase 3),
|
|
8
|
+
* so path-clamp and decoding logic has a single source of truth instead of being
|
|
9
|
+
* reimplemented per consumer.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveWriteTargetPath(projectRoot: string, fileTarget: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Writes every `files[]` entry of a validated registry entry into `projectRoot`, honoring
|
|
14
|
+
* each file's `target` and `encoding`. Pure I/O helper: no fetch, no CLI concerns.
|
|
15
|
+
*/
|
|
16
|
+
export declare function writeRegistryEntryFiles(entry: Pick<RegistryEntry, 'files'>, projectRoot: string): Promise<WriteResult[]>;
|
|
17
|
+
//# sourceMappingURL=resolve-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-write.d.ts","sourceRoot":"","sources":["../src/resolve-write.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,aAAa,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAatF;AAQD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC,EACnC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,EAAE,CAAC,CAUxB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Shared by the spike injector (`scripts/inject-spike.mjs`) and the future CLI (Phase 3),
|
|
5
|
+
* so path-clamp and decoding logic has a single source of truth instead of being
|
|
6
|
+
* reimplemented per consumer.
|
|
7
|
+
*/
|
|
8
|
+
export function resolveWriteTargetPath(projectRoot, fileTarget) {
|
|
9
|
+
if (isAbsolute(fileTarget)) {
|
|
10
|
+
throw new Error(`Refusing to write outside target root: "${fileTarget}" is an absolute path`);
|
|
11
|
+
}
|
|
12
|
+
const root = resolve(projectRoot);
|
|
13
|
+
const resolved = resolve(root, fileTarget);
|
|
14
|
+
const rootWithSep = root.endsWith('/') ? root : `${root}/`;
|
|
15
|
+
if (resolved !== root && !resolved.startsWith(rootWithSep)) {
|
|
16
|
+
throw new Error(`Refusing to write outside target root: "${fileTarget}" escapes "${projectRoot}"`);
|
|
17
|
+
}
|
|
18
|
+
return resolved;
|
|
19
|
+
}
|
|
20
|
+
function decodeFileContent(file) {
|
|
21
|
+
return file.encoding === 'base64'
|
|
22
|
+
? Buffer.from(file.content, 'base64')
|
|
23
|
+
: Buffer.from(file.content, 'utf8');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Writes every `files[]` entry of a validated registry entry into `projectRoot`, honoring
|
|
27
|
+
* each file's `target` and `encoding`. Pure I/O helper: no fetch, no CLI concerns.
|
|
28
|
+
*/
|
|
29
|
+
export async function writeRegistryEntryFiles(entry, projectRoot) {
|
|
30
|
+
const results = [];
|
|
31
|
+
for (const file of entry.files) {
|
|
32
|
+
const destination = resolveWriteTargetPath(projectRoot, file.target);
|
|
33
|
+
const content = decodeFileContent(file);
|
|
34
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
35
|
+
await writeFile(destination, content);
|
|
36
|
+
results.push({ target: destination, bytesWritten: content.byteLength });
|
|
37
|
+
}
|
|
38
|
+
return results;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=resolve-write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-write.js","sourceRoot":"","sources":["../src/resolve-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzD;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB,EAAE,UAAkB;IAC5E,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,2CAA2C,UAAU,uBAAuB,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC;IAC3D,IAAI,QAAQ,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,2CAA2C,UAAU,cAAc,WAAW,GAAG,CAClF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,IAA6B;IACtD,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;QAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;QACrC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,KAAmC,EACnC,WAAmB;IAEnB,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACxC,MAAM,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Descriptor types for a ModularCore registry component (`modularcore.json`).
|
|
3
|
+
* Runtime validation lives in `schema.zod.ts`; keep both in sync.
|
|
4
|
+
*/
|
|
5
|
+
/** Extensible component kind. New kinds (e.g. `agent-tool`) can be added without breaking existing descriptors. */
|
|
6
|
+
export type ComponentType = 'frontend-component' | 'headless-core' | 'snippet' | (string & {});
|
|
7
|
+
export type SupportedFramework = 'react' | 'svelte' | (string & {});
|
|
8
|
+
/** `internal` components are built and locally resolvable but excluded from the public `index.json`. */
|
|
9
|
+
export type Visibility = 'public' | 'internal';
|
|
10
|
+
export type FileEncoding = 'utf8' | 'base64';
|
|
11
|
+
export interface EnvVariableDescriptor {
|
|
12
|
+
key: string;
|
|
13
|
+
description: string;
|
|
14
|
+
required: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface RegistryFileDescriptor {
|
|
17
|
+
/** Path to the source file, relative to the component's package root (e.g. `packages/{name}/`). */
|
|
18
|
+
path: string;
|
|
19
|
+
/** Path (relative to the consumer project root) where the file should be written when injected. */
|
|
20
|
+
target: string;
|
|
21
|
+
/** File kind, informational for consumers (e.g. `component`, `hook`, `style`). */
|
|
22
|
+
type: string;
|
|
23
|
+
encoding: FileEncoding;
|
|
24
|
+
}
|
|
25
|
+
export interface RegistryDescriptor {
|
|
26
|
+
name: string;
|
|
27
|
+
version: string;
|
|
28
|
+
title: string;
|
|
29
|
+
type: ComponentType;
|
|
30
|
+
category: string;
|
|
31
|
+
frameworks: SupportedFramework[];
|
|
32
|
+
visibility: Visibility;
|
|
33
|
+
/** Semver ranges keyed by peer framework, e.g. `{ "react": ">=18" }`. Gates `add` (Phase 3) before writing runes/hooks. */
|
|
34
|
+
peerDependencies: Record<string, string>;
|
|
35
|
+
dependencies: string[];
|
|
36
|
+
registryDependencies: string[];
|
|
37
|
+
envVariables: EnvVariableDescriptor[];
|
|
38
|
+
files: RegistryFileDescriptor[];
|
|
39
|
+
description?: string;
|
|
40
|
+
}
|
|
41
|
+
/** A file descriptor plus its resolved content, as embedded inline into `{name}.json`. */
|
|
42
|
+
export interface RegistryFileWithContent extends RegistryFileDescriptor {
|
|
43
|
+
content: string;
|
|
44
|
+
}
|
|
45
|
+
/** Full descriptor as served at `/registry/{name}.json`. */
|
|
46
|
+
export interface RegistryEntry extends Omit<RegistryDescriptor, 'files'> {
|
|
47
|
+
files: RegistryFileWithContent[];
|
|
48
|
+
}
|
|
49
|
+
/** Summarized entry as served at `/registry/index.json`. Excludes `visibility: internal` entries. */
|
|
50
|
+
export interface RegistryIndexEntry {
|
|
51
|
+
name: string;
|
|
52
|
+
title: string;
|
|
53
|
+
category: string;
|
|
54
|
+
version: string;
|
|
55
|
+
frameworks: SupportedFramework[];
|
|
56
|
+
description?: string;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mHAAmH;AACnH,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,eAAe,GAAG,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/F,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,QAAQ,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAEpE,wGAAwG;AACxG,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7C,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,mGAAmG;IACnG,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,MAAM,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,UAAU,EAAE,UAAU,CAAC;IACvB,2HAA2H;IAC3H,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,YAAY,EAAE,qBAAqB,EAAE,CAAC;IACtC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,0FAA0F;AAC1F,MAAM,WAAW,uBAAwB,SAAQ,sBAAsB;IACrE,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACtE,KAAK,EAAE,uBAAuB,EAAE,CAAC;CAClC;AAED,qGAAqG;AACrG,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const envVariableSchema: z.ZodObject<{
|
|
3
|
+
key: z.ZodString;
|
|
4
|
+
description: z.ZodString;
|
|
5
|
+
required: z.ZodBoolean;
|
|
6
|
+
}, z.core.$strip>;
|
|
7
|
+
export declare const fileEncodingSchema: z.ZodEnum<{
|
|
8
|
+
utf8: "utf8";
|
|
9
|
+
base64: "base64";
|
|
10
|
+
}>;
|
|
11
|
+
export declare const registryFileSchema: z.ZodObject<{
|
|
12
|
+
path: z.ZodString;
|
|
13
|
+
target: z.ZodString;
|
|
14
|
+
type: z.ZodString;
|
|
15
|
+
encoding: z.ZodEnum<{
|
|
16
|
+
utf8: "utf8";
|
|
17
|
+
base64: "base64";
|
|
18
|
+
}>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export declare const componentTypeSchema: z.ZodUnion<readonly [z.ZodEnum<{
|
|
21
|
+
"frontend-component": "frontend-component";
|
|
22
|
+
"headless-core": "headless-core";
|
|
23
|
+
snippet: "snippet";
|
|
24
|
+
}>, z.ZodString]>;
|
|
25
|
+
export declare const visibilitySchema: z.ZodDefault<z.ZodEnum<{
|
|
26
|
+
public: "public";
|
|
27
|
+
internal: "internal";
|
|
28
|
+
}>>;
|
|
29
|
+
export declare const registryDescriptorSchema: z.ZodObject<{
|
|
30
|
+
name: z.ZodString;
|
|
31
|
+
version: z.ZodString;
|
|
32
|
+
title: z.ZodString;
|
|
33
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
34
|
+
"frontend-component": "frontend-component";
|
|
35
|
+
"headless-core": "headless-core";
|
|
36
|
+
snippet: "snippet";
|
|
37
|
+
}>, z.ZodString]>;
|
|
38
|
+
category: z.ZodString;
|
|
39
|
+
frameworks: z.ZodArray<z.ZodString>;
|
|
40
|
+
visibility: z.ZodDefault<z.ZodEnum<{
|
|
41
|
+
public: "public";
|
|
42
|
+
internal: "internal";
|
|
43
|
+
}>>;
|
|
44
|
+
peerDependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
45
|
+
dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
46
|
+
registryDependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
47
|
+
envVariables: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
48
|
+
key: z.ZodString;
|
|
49
|
+
description: z.ZodString;
|
|
50
|
+
required: z.ZodBoolean;
|
|
51
|
+
}, z.core.$strip>>>;
|
|
52
|
+
files: z.ZodArray<z.ZodObject<{
|
|
53
|
+
path: z.ZodString;
|
|
54
|
+
target: z.ZodString;
|
|
55
|
+
type: z.ZodString;
|
|
56
|
+
encoding: z.ZodEnum<{
|
|
57
|
+
utf8: "utf8";
|
|
58
|
+
base64: "base64";
|
|
59
|
+
}>;
|
|
60
|
+
}, z.core.$strip>>;
|
|
61
|
+
description: z.ZodOptional<z.ZodString>;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
export type RegistryDescriptorInput = z.input<typeof registryDescriptorSchema>;
|
|
64
|
+
export type RegistryDescriptorParsed = z.output<typeof registryDescriptorSchema>;
|
|
65
|
+
export declare const registryFileWithContentSchema: z.ZodObject<{
|
|
66
|
+
path: z.ZodString;
|
|
67
|
+
target: z.ZodString;
|
|
68
|
+
type: z.ZodString;
|
|
69
|
+
encoding: z.ZodEnum<{
|
|
70
|
+
utf8: "utf8";
|
|
71
|
+
base64: "base64";
|
|
72
|
+
}>;
|
|
73
|
+
content: z.ZodString;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
export declare const registryEntrySchema: z.ZodObject<{
|
|
76
|
+
type: z.ZodUnion<readonly [z.ZodEnum<{
|
|
77
|
+
"frontend-component": "frontend-component";
|
|
78
|
+
"headless-core": "headless-core";
|
|
79
|
+
snippet: "snippet";
|
|
80
|
+
}>, z.ZodString]>;
|
|
81
|
+
description: z.ZodOptional<z.ZodString>;
|
|
82
|
+
visibility: z.ZodDefault<z.ZodEnum<{
|
|
83
|
+
public: "public";
|
|
84
|
+
internal: "internal";
|
|
85
|
+
}>>;
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
version: z.ZodString;
|
|
88
|
+
title: z.ZodString;
|
|
89
|
+
category: z.ZodString;
|
|
90
|
+
frameworks: z.ZodArray<z.ZodString>;
|
|
91
|
+
peerDependencies: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
92
|
+
dependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
93
|
+
registryDependencies: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
94
|
+
envVariables: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
95
|
+
key: z.ZodString;
|
|
96
|
+
description: z.ZodString;
|
|
97
|
+
required: z.ZodBoolean;
|
|
98
|
+
}, z.core.$strip>>>;
|
|
99
|
+
files: z.ZodArray<z.ZodObject<{
|
|
100
|
+
path: z.ZodString;
|
|
101
|
+
target: z.ZodString;
|
|
102
|
+
type: z.ZodString;
|
|
103
|
+
encoding: z.ZodEnum<{
|
|
104
|
+
utf8: "utf8";
|
|
105
|
+
base64: "base64";
|
|
106
|
+
}>;
|
|
107
|
+
content: z.ZodString;
|
|
108
|
+
}, z.core.$strip>>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export declare const registryIndexEntrySchema: z.ZodObject<{
|
|
111
|
+
name: z.ZodString;
|
|
112
|
+
title: z.ZodString;
|
|
113
|
+
category: z.ZodString;
|
|
114
|
+
version: z.ZodString;
|
|
115
|
+
frameworks: z.ZodArray<z.ZodString>;
|
|
116
|
+
description: z.ZodOptional<z.ZodString>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
//# sourceMappingURL=schema.zod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.zod.d.ts","sourceRoot":"","sources":["../src/schema.zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,eAAO,MAAM,iBAAiB;;;;iBAI5B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;EAA6B,CAAC;AAE7D,eAAO,MAAM,kBAAkB;;;;;;;;iBAK7B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;iBAG9B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;GAAmD,CAAC;AAEjF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAiBnC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC/E,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEjF,eAAO,MAAM,6BAA6B;;;;;;;;;iBAExC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAEmC,CAAC;AAEpE,eAAO,MAAM,wBAAwB;;;;;;;iBAOnC,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* SA1 (red-team, Critical): a malicious/misconfigured `files[].path` (e.g. `../../.env`
|
|
4
|
+
* or an absolute path) must never be accepted at the schema level, so the builder can
|
|
5
|
+
* trust `path` before doing its own filesystem-level clamp (defense in depth).
|
|
6
|
+
*/
|
|
7
|
+
function isSafeRelativePath(value) {
|
|
8
|
+
if (value.length === 0)
|
|
9
|
+
return false;
|
|
10
|
+
if (value.startsWith('/') || value.startsWith('\\'))
|
|
11
|
+
return false;
|
|
12
|
+
// Windows drive letter, e.g. "C:\\..."
|
|
13
|
+
if (/^[a-zA-Z]:/.test(value))
|
|
14
|
+
return false;
|
|
15
|
+
const segments = value.split(/[\\/]/);
|
|
16
|
+
return !segments.includes('..');
|
|
17
|
+
}
|
|
18
|
+
const safeRelativePathSchema = z.string().refine(isSafeRelativePath, {
|
|
19
|
+
message: 'Path must be relative and must not contain ".." or an absolute prefix',
|
|
20
|
+
});
|
|
21
|
+
export const envVariableSchema = z.object({
|
|
22
|
+
key: z.string().min(1),
|
|
23
|
+
description: z.string().min(1),
|
|
24
|
+
required: z.boolean(),
|
|
25
|
+
});
|
|
26
|
+
export const fileEncodingSchema = z.enum(['utf8', 'base64']);
|
|
27
|
+
export const registryFileSchema = z.object({
|
|
28
|
+
path: safeRelativePathSchema,
|
|
29
|
+
target: safeRelativePathSchema,
|
|
30
|
+
type: z.string().min(1),
|
|
31
|
+
encoding: fileEncodingSchema,
|
|
32
|
+
});
|
|
33
|
+
export const componentTypeSchema = z.union([
|
|
34
|
+
z.enum(['frontend-component', 'headless-core', 'snippet']),
|
|
35
|
+
z.string().min(1),
|
|
36
|
+
]);
|
|
37
|
+
export const visibilitySchema = z.enum(['public', 'internal']).default('public');
|
|
38
|
+
export const registryDescriptorSchema = z.object({
|
|
39
|
+
name: z
|
|
40
|
+
.string()
|
|
41
|
+
.min(1)
|
|
42
|
+
.regex(/^[a-z0-9][a-z0-9-]*$/, 'name must be kebab-case'),
|
|
43
|
+
version: z.string().min(1),
|
|
44
|
+
title: z.string().min(1),
|
|
45
|
+
type: componentTypeSchema,
|
|
46
|
+
category: z.string().min(1),
|
|
47
|
+
frameworks: z.array(z.string().min(1)).min(1),
|
|
48
|
+
visibility: visibilitySchema,
|
|
49
|
+
peerDependencies: z.record(z.string(), z.string()).default({}),
|
|
50
|
+
dependencies: z.array(z.string()).default([]),
|
|
51
|
+
registryDependencies: z.array(z.string()).default([]),
|
|
52
|
+
envVariables: z.array(envVariableSchema).default([]),
|
|
53
|
+
files: z.array(registryFileSchema).min(1),
|
|
54
|
+
description: z.string().optional(),
|
|
55
|
+
});
|
|
56
|
+
export const registryFileWithContentSchema = registryFileSchema.extend({
|
|
57
|
+
content: z.string(),
|
|
58
|
+
});
|
|
59
|
+
export const registryEntrySchema = registryDescriptorSchema
|
|
60
|
+
.omit({ files: true })
|
|
61
|
+
.extend({ files: z.array(registryFileWithContentSchema).min(1) });
|
|
62
|
+
export const registryIndexEntrySchema = z.object({
|
|
63
|
+
name: z.string(),
|
|
64
|
+
title: z.string(),
|
|
65
|
+
category: z.string(),
|
|
66
|
+
version: z.string(),
|
|
67
|
+
frameworks: z.array(z.string()),
|
|
68
|
+
description: z.string().optional(),
|
|
69
|
+
});
|
|
70
|
+
//# sourceMappingURL=schema.zod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.zod.js","sourceRoot":"","sources":["../src/schema.zod.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RegistryFileWithContent } from './schema.js';
|
|
2
|
+
/**
|
|
3
|
+
* `tar-stream` builds the tar entries in memory (no filesystem round-trip), and
|
|
4
|
+
* `zlib.gzipSync` (Node builtin) compresses the resulting buffer — avoids depending on a
|
|
5
|
+
* full `tar` CLI wrapper package just to produce a `.tar.gz` from in-memory content.
|
|
6
|
+
*/
|
|
7
|
+
export declare function buildTarball(files: RegistryFileWithContent[]): Promise<Buffer>;
|
|
8
|
+
//# sourceMappingURL=tarball.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.d.ts","sourceRoot":"","sources":["../src/tarball.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBpF"}
|
package/dist/tarball.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { gzipSync } from 'node:zlib';
|
|
2
|
+
import { pack } from 'tar-stream';
|
|
3
|
+
/**
|
|
4
|
+
* `tar-stream` builds the tar entries in memory (no filesystem round-trip), and
|
|
5
|
+
* `zlib.gzipSync` (Node builtin) compresses the resulting buffer — avoids depending on a
|
|
6
|
+
* full `tar` CLI wrapper package just to produce a `.tar.gz` from in-memory content.
|
|
7
|
+
*/
|
|
8
|
+
export async function buildTarball(files) {
|
|
9
|
+
const tarPack = pack();
|
|
10
|
+
const chunks = [];
|
|
11
|
+
tarPack.on('data', (chunk) => chunks.push(chunk));
|
|
12
|
+
const done = new Promise((resolvePromise, rejectPromise) => {
|
|
13
|
+
tarPack.on('end', () => resolvePromise(Buffer.concat(chunks)));
|
|
14
|
+
tarPack.on('error', rejectPromise);
|
|
15
|
+
});
|
|
16
|
+
for (const file of files) {
|
|
17
|
+
const content = file.encoding === 'base64'
|
|
18
|
+
? Buffer.from(file.content, 'base64')
|
|
19
|
+
: Buffer.from(file.content, 'utf8');
|
|
20
|
+
await new Promise((resolveEntry, rejectEntry) => {
|
|
21
|
+
tarPack.entry({ name: file.target }, content, (error) => error ? rejectEntry(error) : resolveEntry());
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
tarPack.finalize();
|
|
25
|
+
const tarBuffer = await done;
|
|
26
|
+
return gzipSync(tarBuffer);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=tarball.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tarball.js","sourceRoot":"","sources":["../src/tarball.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAIlC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,KAAgC;IACjE,MAAM,OAAO,GAAG,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAE1D,MAAM,IAAI,GAAG,IAAI,OAAO,CAAS,CAAC,cAAc,EAAE,aAAa,EAAE,EAAE;QACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GACX,IAAI,CAAC,QAAQ,KAAK,QAAQ;YACxB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC;YACrC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxC,MAAM,IAAI,OAAO,CAAO,CAAC,YAAY,EAAE,WAAW,EAAE,EAAE;YACpD,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CACtD,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAC5C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,QAAQ,EAAE,CAAC;IAEnB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC;IAC7B,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC7B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@modularcore/registry",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"tar-stream": "^3.2.0",
|
|
22
|
+
"zod": "^4.4.3"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^22.13.0",
|
|
26
|
+
"@types/tar-stream": "^3.1.4"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -p tsconfig.json",
|
|
30
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
31
|
+
"test": "vitest run"
|
|
32
|
+
}
|
|
33
|
+
}
|