Skip to content

Commit

Permalink
Improved website emulator
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianRappl committed Oct 15, 2024
1 parent 8a77b03 commit d2d3eb1
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 94 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Fixed issue in `piral-vue3` concerning reactivity of props (#720)
- Updated to latest version of `dets`
- Updated website emulator to contain scaffolding tarballs
- Added support for `shared` key in *piral.json*

## 1.6.2 (September 27, 2024)
Expand Down
174 changes: 87 additions & 87 deletions src/tooling/piral-cli/src/common/emulator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { join, resolve, relative, basename } from 'path';
import { join, resolve, relative, basename, extname } from 'path';
import { findDependencyVersion, copyScaffoldingFiles, isValidDependency, flattenExternals } from './package';
import { createPiralStubIndexIfNotExists } from './template';
import { filesTar, filesOnceTar, packageJson, piralJson, emulatorJson } from './constants';
Expand All @@ -11,25 +11,19 @@ import { createDirectory, removeDirectory, matchFiles, removeAny, getFileNames }
import { updateExistingJson, readJson, writeJson, createFileIfNotExists } from './io';
import { EmulatorWebsiteManifest, LogLevels, SharedDependency, PiletsInfo, TemplateFileLocation } from '../types';

export async function createEmulatorSources(
sourceDir: string,
externals: Array<SharedDependency>,
targetDir: string,
targetFile: string,
logLevel: LogLevels,
) {
const piralPkg = await readJson(sourceDir, packageJson);
const piralJsonPkg = await readJson(sourceDir, piralJson);
const pilets: PiletsInfo = {
...piralPkg.pilets,
...piralJsonPkg.pilets,
};
const files: Array<string | TemplateFileLocation> = pilets.files ?? [];
const allDeps = {
...piralPkg.devDependencies,
...piralPkg.dependencies,
};
function makeFilesMap(files: Array<string | TemplateFileLocation> = []): Array<TemplateFileLocation> {
return files
.filter((file) => file && (typeof file === 'string' || typeof file === 'object'))
.map((file) => (typeof file === 'string' ? { from: file, to: file } : file))
.filter((file) => typeof file.to === 'string' && typeof file.from === 'string')
.map((file) => ({
...file,
to: file.to.replace(/\\/g, '/'),
from: join('files', file.to).replace(/\\/g, '/'),
}));
}

async function makeExternals(sourceDir: string, piralPkg: any, externals: Array<SharedDependency>) {
const externalPackages = await Promise.all(
externals
.filter((ext) => ext.type === 'local' && isValidDependency(ext.name))
Expand Down Expand Up @@ -63,20 +57,66 @@ export async function createEmulatorSources(
return deps;
}, {} as Record<string, string>);

return [externalDependencies, importmapEntries, optionalDependencies] as const;
}

async function createScaffoldingTarballs(sourceDir: string, targetDir: string, files: Array<TemplateFileLocation>) {
const filesDir = resolve(targetDir, filesTar);
const filesOnceDir = resolve(targetDir, filesOnceTar);

await Promise.all([createDirectory(filesDir), createDirectory(filesOnceDir)]);

// for scaffolding we need to keep the files also available in the new package
await copyScaffoldingFiles(
sourceDir,
filesDir,
files.filter((m) => !m.once),
);

// also to avoid information loss we should store the once-only files separately
await copyScaffoldingFiles(
sourceDir,
filesOnceDir,
files.filter((m) => m.once),
);

// since things like .gitignore are not properly treated by npm we pack the files (for standard and once only)
await Promise.all([
createTarball(filesDir, targetDir, `${filesTar}.tar`),
createTarball(filesOnceDir, targetDir, `${filesOnceTar}.tar`),
]);

// ... and remove the directory
await Promise.all([removeDirectory(filesDir), removeDirectory(filesOnceDir)]);
}

export async function createEmulatorSources(
sourceDir: string,
externals: Array<SharedDependency>,
targetDir: string,
targetFile: string,
logLevel: LogLevels,
) {
const piralPkg = await readJson(sourceDir, packageJson);
const piralJsonPkg = await readJson(sourceDir, piralJson);
const pilets: PiletsInfo = {
...piralPkg.pilets,
...piralJsonPkg.pilets,
};
const files = makeFilesMap(pilets.files);
const allDeps = {
...piralPkg.devDependencies,
...piralPkg.dependencies,
};

const rootDir = resolve(targetDir, '..');
const appDir = relative(rootDir, targetDir);
const filesDir = resolve(rootDir, filesTar);
const filesOnceDir = resolve(rootDir, filesOnceTar);

const filesMap = files
.filter((file) => file && (typeof file === 'string' || typeof file === 'object'))
.map((file) => (typeof file === 'string' ? { from: file, to: file } : file))
.filter((file) => typeof file.to === 'string' && typeof file.from === 'string')
.map((file) => ({
...file,
to: file.to.replace(/\\/g, '/'),
from: join('files', file.to).replace(/\\/g, '/'),
}));
const [externalDependencies, importmapEntries, optionalDependencies] = await makeExternals(
sourceDir,
piralPkg,
externals,
);

// do not modify an existing JSON
await createFileIfNotExists(rootDir, packageJson, '{}');
Expand All @@ -94,7 +134,7 @@ export async function createEmulatorSources(
},
pilets: {
...pilets,
files: filesMap,
files,
},
piralCLI: {
version: cliVersion,
Expand All @@ -119,22 +159,6 @@ export async function createEmulatorSources(
publishConfig: piralPkg.publishConfig,
});

await Promise.all([createDirectory(filesDir), createDirectory(filesOnceDir)]);

// for scaffolding we need to keep the files also available in the new package
await copyScaffoldingFiles(
sourceDir,
filesDir,
files.filter((m) => typeof m === 'string' || !m.once),
);

// also to avoid information loss we should store the once-only files separately
await copyScaffoldingFiles(
sourceDir,
filesOnceDir,
files.filter((m) => typeof m !== 'string' && m.once),
);

// we just want to make sure that "files" mentioned in the original package.json are respected in the package
await copyScaffoldingFiles(sourceDir, rootDir, piralPkg.files ?? []);

Expand All @@ -147,14 +171,8 @@ export async function createEmulatorSources(
// generate the associated index.d.ts
await createPiralDeclaration(sourceDir, piralPkg.app ?? `./src/index.html`, targetDir, ForceOverwrite.yes, logLevel);

// since things like .gitignore are not properly treated by npm we pack the files (for standard and once only)
await Promise.all([
createTarball(filesDir, rootDir, `${filesTar}.tar`),
createTarball(filesOnceDir, rootDir, `${filesOnceTar}.tar`),
]);

// ... and remove the directory
await Promise.all([removeDirectory(filesDir), removeDirectory(filesOnceDir)]);
// generate the files.tar and files_once.tar files
await createScaffoldingTarballs(sourceDir, rootDir, files);

return rootDir;
}
Expand All @@ -172,43 +190,17 @@ export async function createEmulatorWebsite(
...piralPkg.pilets,
...piralJsonPkg.pilets,
};
const files = makeFilesMap(pilets.files);
const allDeps = {
...piralPkg.devDependencies,
...piralPkg.dependencies,
};

const externalPackages = await Promise.all(
externals
.filter((ext) => ext.type === 'local' && isValidDependency(ext.name))
.map(async (external) => ({
name: external.name,
version: await findDependencyVersion(piralPkg, sourceDir, external),
optional: external.isAsync,
})),
const [externalDependencies, importmapEntries, optionalDependencies] = await makeExternals(
sourceDir,
piralPkg,
externals,
);
const externalDependencies = externalPackages.reduce((deps, dep) => {
if (!dep.optional) {
deps[dep.name] = dep.version;
}

return deps;
}, {} as Record<string, string>);

const importmapEntries = externalPackages.reduce((deps, dep) => {
if (!dep.optional) {
deps[dep.name] = dep.name;
}

return deps;
}, {} as Record<string, string>);

const optionalDependencies = externalPackages.reduce((deps, dep) => {
if (dep.optional) {
deps[dep.name] = dep.name;
}

return deps;
}, {} as Record<string, string>);

const allFiles = await matchFiles(targetDir, '*');
const data: EmulatorWebsiteManifest = {
Expand All @@ -217,13 +209,18 @@ export async function createEmulatorWebsite(
version: piralPkg.version,
timestamp: new Date().toISOString(),
scaffolding: {
pilets,
pilets: {
...pilets,
files,
},
cli: cliVersion,
},
files: {
typings: 'index.d.ts',
main: basename(targetFile),
app: 'index.html',
always: `${filesTar}.tar`,
once: `${filesOnceTar}.tar`,
assets: allFiles.map((file) => relative(targetDir, file)),
},
importmap: {
Expand All @@ -243,6 +240,9 @@ export async function createEmulatorWebsite(
// generate the associated index.d.ts
await createPiralDeclaration(sourceDir, piralPkg.app ?? `./src/index.html`, targetDir, ForceOverwrite.yes, logLevel);

// generate the files.tar and files_once.tar files
await createScaffoldingTarballs(sourceDir, targetDir, files);

return targetDir;
}

Expand Down
16 changes: 9 additions & 7 deletions src/tooling/piral-cli/src/common/website.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,18 @@ async function downloadEmulatorFiles(
files: EmulatorWebsiteManifestFiles,
httpsAgent?: Agent,
) {
const requiredFiles = [files.typings, files.main, files.app];
const requiredFiles = [files.typings, files.main, files.app, files.always, files.once];
const opts = getAxiosOptions(manifestUrl);

await Promise.all(
requiredFiles.map(async (file) => {
const url = new URL(file, manifestUrl);
const res = await axios.default.get(url.href, { ...opts, httpsAgent, responseType: 'arraybuffer' });
const data: Buffer = res.data;
await writeBinary(target, file, data);
}),
requiredFiles
.filter((file) => file && typeof file === 'string')
.map(async (file) => {
const url = new URL(file, manifestUrl);
const res = await axios.default.get(url.href, { ...opts, httpsAgent, responseType: 'arraybuffer' });
const data: Buffer = res.data;
await writeBinary(target, file, data);
}),
);
}

Expand Down
2 changes: 2 additions & 0 deletions src/tooling/piral-cli/src/types/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export interface EmulatorWebsiteManifestFiles {
main: string;
app: string;
assets: Array<string>;
always?: string;
once?: string;
}

export interface EmulatorWebsiteManifest {
Expand Down

0 comments on commit d2d3eb1

Please sign in to comment.