Skip to content

Commit

Permalink
Make project.description optional
Browse files Browse the repository at this point in the history
  • Loading branch information
Florens Verschelde committed Mar 10, 2023
1 parent ca0ecc6 commit 4615fe5
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 30 deletions.
56 changes: 31 additions & 25 deletions src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,50 +16,56 @@ function createHiddenInput(name: string, value: string) {
* with custom escape sequences. Important: do not encodeURIComponent the
* whole path, for compatibility with the StackBlitz backend.
*/
function bracketedFilePath(path: string) {
return `[${path.replace(/\[/g, '%5B').replace(/\]/g, '%5D')}]`;
function encodeFilePath(path: string) {
return path.replace(/\[/g, '%5B').replace(/\]/g, '%5D');
}

export function createProjectForm(project: Project) {
if (!PROJECT_TEMPLATES.includes(project.template)) {
export function createProjectForm({
template,
title,
description,
dependencies,
files,
settings,
}: Project) {
if (!PROJECT_TEMPLATES.includes(template)) {
const names = PROJECT_TEMPLATES.map((t) => `'${t}'`).join(', ');
console.warn(`Unsupported project.template: must be one of ${names}`);
}

const isWebContainers = project.template === 'node';
const inputs: HTMLInputElement[] = [];
const addInput = (name: string, value: string, defaultValue = '') => {
inputs.push(createHiddenInput(name, typeof value === 'string' ? value : defaultValue));
};

const form = document.createElement('form');
form.method = 'POST';
form.setAttribute('style', 'display:none!important;');

form.appendChild(createHiddenInput('project[title]', project.title));
form.appendChild(createHiddenInput('project[description]', project.description));
form.appendChild(createHiddenInput('project[template]', project.template));
addInput('project[title]', title);
if (typeof description === 'string' && description.length > 0) {
addInput('project[description]', description);
}
addInput('project[template]', template, 'javascript');

if (project.dependencies) {
if (isWebContainers) {
if (dependencies) {
if (template === 'node') {
console.warn(
`Invalid project.dependencies: dependencies must be provided as a 'package.json' file when using the 'node' template.`
);
} else {
form.appendChild(
createHiddenInput('project[dependencies]', JSON.stringify(project.dependencies))
);
addInput('project[dependencies]', JSON.stringify(dependencies));
}
}

if (project.settings) {
form.appendChild(createHiddenInput('project[settings]', JSON.stringify(project.settings)));
if (settings) {
addInput('project[settings]', JSON.stringify(settings));
}

Object.keys(project.files).forEach((path) => {
const name = 'project[files]' + bracketedFilePath(path);
const value = project.files[path];
if (typeof value === 'string') {
form.appendChild(createHiddenInput(name, value));
}
Object.entries(files).forEach(([path, contents]) => {
addInput(`project[files][${encodeFilePath(path)}]`, contents);
});

const form = document.createElement('form');
form.method = 'POST';
form.setAttribute('style', 'display:none!important;');
form.append(...inputs);
return form;
}

Expand Down
2 changes: 1 addition & 1 deletion src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { PROJECT_TEMPLATES } from './constants';

export interface Project {
title: string;
description: string;
description?: string;
/**
* The project’s template name tells StackBlitz how to compile and run project files.
*
Expand Down
1 change: 0 additions & 1 deletion test/e2e/embedVm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ test('vm.getFsSnapshot and vm.applyFsDiff', async ({ page }) => {
const project: Project = {
title: 'Test Project',
template: 'html',
description: '',
files: {
'index.html': `<h1>Hello World</h1>`,
'styles.css': `body { color: lime }`,
Expand Down
2 changes: 1 addition & 1 deletion test/unit/__snapshots__/generate.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ exports[`createProjectFrameHTML > generates a HTML document string 1`] = `
<html>
<head><title></title></head>
<body>
<form method=\\"POST\\" style=\\"display:none!important;\\" action=\\"https://stackblitz.com/run?embed=1\\" id=\\"sb_run\\"><input type=\\"hidden\\" name=\\"project[title]\\" value=\\"Test Project\\"><input type=\\"hidden\\" name=\\"project[description]\\" value=\\"This is a test\\"><input type=\\"hidden\\" name=\\"project[template]\\" value=\\"javascript\\"><input type=\\"hidden\\" name=\\"project[files][package.json]\\" value=\\"{
<form method=\\"POST\\" style=\\"display:none!important;\\" action=\\"https://stackblitz.com/run?embed=1\\" id=\\"sb_run\\"><input type=\\"hidden\\" name=\\"project[title]\\" value=\\"Test Project\\"><input type=\\"hidden\\" name=\\"project[template]\\" value=\\"javascript\\"><input type=\\"hidden\\" name=\\"project[files][package.json]\\" value=\\"{
&quot;dependencies&quot;: {&quot;cowsay&quot;: &quot;1.5.0&quot;}
}\\"><input type=\\"hidden\\" name=\\"project[files][index.js]\\" value=\\"import cowsay from &#x27;cowsay&#x27;;
console.log(cowsay(&#x27;Hello world!&#x27;));
Expand Down
2 changes: 1 addition & 1 deletion test/unit/generate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('createProjectForm', () => {

// Check input values
expect(value('project[title]')).toBe('My Test Project');
expect(value('project[description]')).toBe(project.description);
expect(value('project[description]')).toBe(undefined);
expect(value('project[template]')).toBe(project.template);
expect(value('project[dependencies]')).toBe(JSON.stringify(project.dependencies));
expect(value('project[settings]')).toBe(JSON.stringify(project.settings));
Expand Down
1 change: 0 additions & 1 deletion test/unit/utils/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Project } from '$src/index';
export function getTestProject(project?: Partial<Project>): Project {
return {
title: 'Test Project',
description: 'This is a test',
template: 'javascript',
files: {
'package.json': `{
Expand Down

0 comments on commit 4615fe5

Please sign in to comment.