mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Add version file (#1087)
This commit is contained in:
@@ -1,48 +1,24 @@
|
||||
import { FetchError, ErrorCode } from "./exceptions";
|
||||
import { FetchError, ErrorCode } from './exceptions';
|
||||
|
||||
|
||||
/*
|
||||
This is a fetch wrapper that handles any non 200 response and throws a FetchError
|
||||
with the right ErrorCode.
|
||||
TODO: Should we only throw on 4xx and 5xx responses?
|
||||
*/
|
||||
export async function robustFetch(url: string, options?: RequestInit): Promise<Response> {
|
||||
const response = await fetch(url, options);
|
||||
// Note that response.ok is true for 200-299 responses
|
||||
if (!response.ok) {
|
||||
const errorMsg = `Fetching from URL ${url} failed with error ${response.status} (${response.statusText}).`;
|
||||
switch(response.status) {
|
||||
switch (response.status) {
|
||||
case 404:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_NOT_FOUND_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_NOT_FOUND_ERROR, errorMsg);
|
||||
case 401:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_UNAUTHORIZED_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_UNAUTHORIZED_ERROR, errorMsg);
|
||||
case 403:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_FORBIDDEN_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_FORBIDDEN_ERROR, errorMsg);
|
||||
case 500:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_SERVER_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_SERVER_ERROR, errorMsg);
|
||||
case 503:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_UNAVAILABLE_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_UNAVAILABLE_ERROR, errorMsg);
|
||||
default:
|
||||
throw new FetchError(
|
||||
ErrorCode.FETCH_ERROR,
|
||||
errorMsg
|
||||
);
|
||||
throw new FetchError(ErrorCode.FETCH_ERROR, errorMsg);
|
||||
}
|
||||
}
|
||||
return response
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import './styles/pyscript_base.css';
|
||||
import { loadConfigFromElement } from './pyconfig';
|
||||
import type { AppConfig } from './pyconfig';
|
||||
import type { Runtime } from './runtime';
|
||||
import { version } from './runtime';
|
||||
import { version } from './version';
|
||||
import { PluginManager, define_custom_element } from './plugin';
|
||||
import { make_PyScript, initHandlers, mountElements } from './components/pyscript';
|
||||
import { PyodideRuntime } from './pyodide';
|
||||
@@ -11,7 +11,7 @@ import { getLogger } from './logger';
|
||||
import { handleFetchError, showWarning, globalExport } from './utils';
|
||||
import { calculatePaths } from './plugins/fetch';
|
||||
import { createCustomElements } from './components/elements';
|
||||
import { UserError, ErrorCode, _createAlertBanner } from "./exceptions"
|
||||
import { UserError, ErrorCode, _createAlertBanner } from './exceptions';
|
||||
import { type Stdio, StdioMultiplexer, DEFAULT_STDIO } from './stdio';
|
||||
import { PyTerminalPlugin } from './plugins/pyterminal';
|
||||
import { SplashscreenPlugin } from './plugins/splashscreen';
|
||||
@@ -180,7 +180,7 @@ export class PyScriptApp {
|
||||
this.plugins.afterSetup(runtime);
|
||||
|
||||
//Refresh module cache in case plugins have modified the filesystem
|
||||
runtime.invalidate_module_path_cache()
|
||||
runtime.invalidate_module_path_cache();
|
||||
this.logStatus('Executing <py-script> tags...');
|
||||
this.executeScripts(runtime);
|
||||
|
||||
@@ -208,7 +208,7 @@ export class PyScriptApp {
|
||||
// Save and load pyscript.py from FS
|
||||
runtime.interpreter.FS.writeFile('pyscript.py', pyscript, { encoding: 'utf8' });
|
||||
//Refresh the module cache so Python consistently finds pyscript module
|
||||
runtime.invalidate_module_path_cache()
|
||||
runtime.invalidate_module_path_cache();
|
||||
|
||||
// inject `define_custom_element` and showWarning it into the PyScript
|
||||
// module scope
|
||||
@@ -224,7 +224,7 @@ export class PyScriptApp {
|
||||
import pyscript
|
||||
from pyscript import Element, display, HTML
|
||||
pyscript._install_deprecated_globals_2022_12_1(globals())
|
||||
`)
|
||||
`);
|
||||
|
||||
if (this.config.packages) {
|
||||
logger.info('Packages to install: ', this.config.packages);
|
||||
@@ -233,7 +233,7 @@ export class PyScriptApp {
|
||||
await this.fetchPaths(runtime);
|
||||
|
||||
//This may be unnecessary - only useful if plugins try to import files fetch'd in fetchPaths()
|
||||
runtime.invalidate_module_path_cache()
|
||||
runtime.invalidate_module_path_cache();
|
||||
// Finally load plugins
|
||||
await this.fetchPythonPlugins(runtime);
|
||||
}
|
||||
@@ -282,7 +282,7 @@ export class PyScriptApp {
|
||||
await runtime.loadFromFile(destPath, singleFile);
|
||||
|
||||
//refresh module cache before trying to import module files into runtime
|
||||
runtime.invalidate_module_path_cache()
|
||||
runtime.invalidate_module_path_cache();
|
||||
|
||||
const modulename = singleFile.replace(/^.*[\\/]/, '').replace('.py', '');
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import toml from '../src/toml';
|
||||
import { getLogger } from './logger';
|
||||
import { version } from './runtime';
|
||||
import { version } from './version';
|
||||
import { getAttribute, readTextFromPath, htmlDecode } from './utils';
|
||||
import { UserError, ErrorCode } from "./exceptions"
|
||||
import { UserError, ErrorCode } from './exceptions';
|
||||
|
||||
const logger = getLogger('py-config');
|
||||
|
||||
@@ -146,7 +146,7 @@ function parseConfig(configText: string, configType = 'toml') {
|
||||
if (configText.trim()[0] === '{') {
|
||||
throw new UserError(
|
||||
ErrorCode.BAD_CONFIG,
|
||||
`The config supplied: ${configText} is an invalid TOML and cannot be parsed`
|
||||
`The config supplied: ${configText} is an invalid TOML and cannot be parsed`,
|
||||
);
|
||||
}
|
||||
return toml.parse(configText);
|
||||
@@ -154,7 +154,7 @@ function parseConfig(configText: string, configType = 'toml') {
|
||||
const errMessage: string = err.toString();
|
||||
throw new UserError(
|
||||
ErrorCode.BAD_CONFIG,
|
||||
`The config supplied: ${configText} is an invalid TOML and cannot be parsed: ${errMessage}`
|
||||
`The config supplied: ${configText} is an invalid TOML and cannot be parsed: ${errMessage}`,
|
||||
);
|
||||
}
|
||||
} else if (configType === 'json') {
|
||||
@@ -170,7 +170,7 @@ function parseConfig(configText: string, configType = 'toml') {
|
||||
} else {
|
||||
throw new UserError(
|
||||
ErrorCode.BAD_CONFIG,
|
||||
`The type of config supplied '${configType}' is not supported, supported values are ["toml", "json"]`
|
||||
`The type of config supplied '${configType}' is not supported, supported values are ["toml", "json"]`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,6 @@ import { getLogger } from './logger';
|
||||
|
||||
const logger = getLogger('pyscript/runtime');
|
||||
|
||||
// VERSION
|
||||
// Version number of release
|
||||
export const version = '2022.12.1.dev';
|
||||
|
||||
export type RuntimeInterpreter = PyodideInterface | null;
|
||||
|
||||
/*
|
||||
|
||||
10
pyscriptjs/src/version.ts
Normal file
10
pyscriptjs/src/version.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @fileoverview Version of pyscript
|
||||
* The version is based on calver which contains YEAR.MONTH.DAY.MODIFIER.
|
||||
* The Modifier can be an optional text tag, such as "dev", "rc", etc.
|
||||
*
|
||||
* We are adding this file because we can't add version in main.js due to
|
||||
* circular imports.
|
||||
*/
|
||||
|
||||
export const version = '2022.12.1.dev';
|
||||
@@ -1,7 +1,7 @@
|
||||
import { jest, describe, it, expect, } from '@jest/globals';
|
||||
import { jest, describe, it, expect } from '@jest/globals';
|
||||
import { loadConfigFromElement, defaultConfig } from '../../src/pyconfig';
|
||||
import { version } from '../../src/runtime';
|
||||
import { UserError } from '../../src/exceptions'
|
||||
import { version } from '../../src/version';
|
||||
import { UserError } from '../../src/exceptions';
|
||||
|
||||
// inspired by trump typos
|
||||
const covfefeConfig = {
|
||||
@@ -27,7 +27,6 @@ name = "covfefe"
|
||||
lang = "covfefe"
|
||||
`;
|
||||
|
||||
|
||||
// ideally, I would like to be able to just do "new HTMLElement" in the tests
|
||||
// below, but it is not permitted. The easiest work around is to create a fake
|
||||
// custom element: not that we are not using any specific feature of custom
|
||||
@@ -48,7 +47,6 @@ function make_config_element(attrs) {
|
||||
return el;
|
||||
}
|
||||
|
||||
|
||||
describe('loadConfigFromElement', () => {
|
||||
const xhrMockClass = () => ({
|
||||
open: jest.fn(),
|
||||
@@ -92,7 +90,6 @@ describe('loadConfigFromElement', () => {
|
||||
expect(config.schema_version).toBe(1);
|
||||
});
|
||||
|
||||
|
||||
it('should load the JSON config from both inline and src', () => {
|
||||
const el = make_config_element({ type: 'json', src: '/covfefe.json' });
|
||||
el.innerHTML = JSON.stringify({ version: '0.2a', wonderful: 'hijacked' });
|
||||
@@ -123,42 +120,48 @@ describe('loadConfigFromElement', () => {
|
||||
it('should NOT be able to load an inline config in JSON format with type as TOML', () => {
|
||||
const el = make_config_element({});
|
||||
el.innerHTML = JSON.stringify(covfefeConfig);
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(/config supplied: {.*} is an invalid TOML and cannot be parsed/);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(
|
||||
/config supplied: {.*} is an invalid TOML and cannot be parsed/,
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT be able to load an inline config in TOML format with type as JSON', () => {
|
||||
const el = make_config_element({ type: 'json' });
|
||||
el.innerHTML = covfefeConfigToml;
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(UserError);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(UserError);
|
||||
});
|
||||
|
||||
it('should NOT be able to load an inline TOML config with a JSON config from src with type as toml', () => {
|
||||
const el = make_config_element({ src: '/covfefe.json' });
|
||||
el.innerHTML = covfefeConfigToml;
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(/config supplied: {.*} is an invalid TOML and cannot be parsed/);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(
|
||||
/config supplied: {.*} is an invalid TOML and cannot be parsed/,
|
||||
);
|
||||
});
|
||||
|
||||
it('should NOT be able to load an inline TOML config with a JSON config from src with type as json', () => {
|
||||
const el = make_config_element({ type: 'json', src: '/covfefe.json' });
|
||||
el.innerHTML = covfefeConfigToml;
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(UserError);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(UserError);
|
||||
});
|
||||
|
||||
it('should error out when passing an invalid JSON', () => {
|
||||
const el = make_config_element({ type: 'json' });
|
||||
el.innerHTML = '[[';
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(UserError);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(UserError);
|
||||
});
|
||||
|
||||
it('should error out when passing an invalid TOML', () => {
|
||||
const el = make_config_element({});
|
||||
el.innerHTML = '[[';
|
||||
expect(()=>loadConfigFromElement(el)).toThrow(UserError);
|
||||
expect(() => loadConfigFromElement(el)).toThrow(UserError);
|
||||
});
|
||||
|
||||
it('should not escape characters like &', () => {
|
||||
const el = make_config_element({ type: 'json'});
|
||||
el.innerHTML = JSON.stringify({ fetch: [{from: 'https://datausa.io/api/data?drilldowns=Nation&measures=Population'}]});
|
||||
const el = make_config_element({ type: 'json' });
|
||||
el.innerHTML = JSON.stringify({
|
||||
fetch: [{ from: 'https://datausa.io/api/data?drilldowns=Nation&measures=Population' }],
|
||||
});
|
||||
const config = loadConfigFromElement(el);
|
||||
expect(config.fetch[0].from).toBe('https://datausa.io/api/data?drilldowns=Nation&measures=Population');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user