functionalscript 0.26.0 → 0.27.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/fs/ci/config/module.f.d.ts +1 -1
- package/fs/ci/config/module.f.js +1 -1
- package/fs/ci/module.f.js +39 -16
- package/fs/ci/proof.f.d.ts +9 -0
- package/fs/ci/proof.f.js +58 -6
- package/fs/dev/package_json/module.f.d.ts +16 -0
- package/fs/dev/package_json/module.f.js +21 -0
- package/fs/dev/package_json/proof.f.d.ts +5 -0
- package/fs/dev/package_json/proof.f.js +23 -0
- package/fs/dev/version/module.f.js +10 -4
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ export declare const node: {
|
|
|
28
28
|
};
|
|
29
29
|
export declare const wasmtime = "45.0.0";
|
|
30
30
|
export declare const wasmer = "7.1.0";
|
|
31
|
-
export declare const tsgo = "7.0.0-dev.
|
|
31
|
+
export declare const tsgo = "7.0.0-dev.20260606.1";
|
|
32
32
|
export declare const actions: {
|
|
33
33
|
readonly 'actions/checkout': "v6";
|
|
34
34
|
readonly 'actions/setup-node': "v6";
|
package/fs/ci/config/module.f.js
CHANGED
|
@@ -36,7 +36,7 @@ export const wasmtime = '45.0.0';
|
|
|
36
36
|
// https://github.com/wasmerio/wasmer/releases
|
|
37
37
|
export const wasmer = '7.1.0';
|
|
38
38
|
// https://www.npmjs.com/package/@typescript/native-preview?activeTab=versions
|
|
39
|
-
export const tsgo = '7.0.0-dev.
|
|
39
|
+
export const tsgo = '7.0.0-dev.20260606.1';
|
|
40
40
|
// GitHub Action versions used by CI step builders. The key is the action
|
|
41
41
|
// `owner/name`; call sites compose the full ref as
|
|
42
42
|
// `` `${name}@${actions[name]}` ``.
|
package/fs/ci/module.f.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
|
-
import { utf8 } from "../text/module.f.js";
|
|
6
|
+
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
7
|
+
import { validatePackageJsonText } from "../dev/package_json/module.f.js";
|
|
7
8
|
import { pure } from "../effects/module.f.js";
|
|
8
|
-
import { access, writeFile } from "../effects/node/module.f.js";
|
|
9
|
+
import { access, readFile, writeFile } from "../effects/node/module.f.js";
|
|
9
10
|
import { images } from "./config/module.f.js";
|
|
10
11
|
import { architecture, findTgz, os, test, toSteps } from "./common/module.f.js";
|
|
11
12
|
import { rustSteps } from "./rust/module.f.js";
|
|
@@ -24,6 +25,20 @@ const job = (rust, nodeExtra, denoExtra, bunExtra) => (o) => (a) => {
|
|
|
24
25
|
];
|
|
25
26
|
return [id, { 'runs-on': image, steps: toSteps(result) }];
|
|
26
27
|
};
|
|
28
|
+
const functionalscriptPackageName = 'functionalscript';
|
|
29
|
+
const fallbackPackageInfo = {
|
|
30
|
+
name: functionalscriptPackageName,
|
|
31
|
+
functionalscript: false,
|
|
32
|
+
};
|
|
33
|
+
const packageInfoFromPackageJson = ({ name }) => name !== undefined
|
|
34
|
+
? { name, functionalscript: name === functionalscriptPackageName }
|
|
35
|
+
: fallbackPackageInfo;
|
|
36
|
+
const packageInfoFromText = (text) => {
|
|
37
|
+
const result = validatePackageJsonText(text);
|
|
38
|
+
return result[0] === 'ok' ? packageInfoFromPackageJson(result[1]) : fallbackPackageInfo;
|
|
39
|
+
};
|
|
40
|
+
const readPackageInfo = readFile('package.json')
|
|
41
|
+
.step(result => pure(result[0] === 'ok' ? packageInfoFromText(utf8ToString(result[1])) : fallbackPackageInfo));
|
|
27
42
|
export const ci = ({ nodeExtra, denoExtra, bunExtra }) => access('Cargo.toml').step(result => {
|
|
28
43
|
const rust = result[0] === 'ok';
|
|
29
44
|
const jobs = {
|
|
@@ -42,21 +57,29 @@ export const ci = ({ nodeExtra, denoExtra, bunExtra }) => access('Cargo.toml').s
|
|
|
42
57
|
return writeFile('.github/workflows/ci.yml', utf8(JSON.stringify(gha, null, ' ')))
|
|
43
58
|
.step(() => pure(0));
|
|
44
59
|
});
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
const demoCompile = [
|
|
61
|
+
test({ run: 'fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
62
|
+
test({ run: 'fjs t' }),
|
|
63
|
+
];
|
|
64
|
+
const denoDemoCompile = [
|
|
65
|
+
test({ run: 'deno task fjs compile issues/demo/data/tree.json _tree.f.js' }),
|
|
66
|
+
test({ run: 'deno task fjs t' }),
|
|
67
|
+
];
|
|
68
|
+
const bunDemoCompile = [
|
|
69
|
+
test({ run: 'bun ./fs/fjs/module.ts t' }),
|
|
70
|
+
];
|
|
71
|
+
const defaultNodeExtra = ({ name, functionalscript }) => (o) => [
|
|
72
|
+
test({ run: 'npm pack' }),
|
|
73
|
+
test({ run: `npm install -g ${findTgz(o)}` }),
|
|
74
|
+
...(functionalscript ? demoCompile : []),
|
|
75
|
+
test({ run: `npm uninstall ${name} -g` }),
|
|
76
|
+
];
|
|
77
|
+
const defaultEffect = (info) => ci({
|
|
78
|
+
nodeExtra: defaultNodeExtra(info),
|
|
53
79
|
denoExtra: [
|
|
54
|
-
|
|
55
|
-
test({ run: 'deno task fjs t' }),
|
|
80
|
+
...(info.functionalscript ? denoDemoCompile : []),
|
|
56
81
|
test({ run: 'deno publish --dry-run --allow-slow-types' }),
|
|
57
82
|
],
|
|
58
|
-
bunExtra: [
|
|
59
|
-
test({ run: 'bun ./fs/fjs/module.ts t' }),
|
|
60
|
-
]
|
|
83
|
+
bunExtra: info.functionalscript ? bunDemoCompile : [],
|
|
61
84
|
});
|
|
62
|
-
export const main = () => defaultEffect;
|
|
85
|
+
export const main = () => readPackageInfo.step(defaultEffect);
|
package/fs/ci/proof.f.d.ts
CHANGED
|
@@ -5,4 +5,13 @@ export declare const proof: {
|
|
|
5
5
|
allOs: () => void;
|
|
6
6
|
osSpecific: () => void;
|
|
7
7
|
};
|
|
8
|
+
defaultSetup: {
|
|
9
|
+
functionalscriptDemo: () => void;
|
|
10
|
+
otherPackageNoDemo: () => void;
|
|
11
|
+
uninstallPackageName: () => void;
|
|
12
|
+
malformedPackageJsonFallback: () => void;
|
|
13
|
+
missingPackageJsonFallback: () => void;
|
|
14
|
+
missingNameFallback: () => void;
|
|
15
|
+
nonObjectFallback: () => void;
|
|
16
|
+
};
|
|
8
17
|
};
|
package/fs/ci/proof.f.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ci } from "./module.f.js";
|
|
2
|
-
import { utf8ToString } from "../text/module.f.js";
|
|
1
|
+
import { ci, main } from "./module.f.js";
|
|
2
|
+
import { utf8, utf8ToString } from "../text/module.f.js";
|
|
3
3
|
import { empty as emptyVec, isVec } from "../types/bit_vec/module.f.js";
|
|
4
4
|
import { test, parseGitHubAction } from "./common/module.f.js";
|
|
5
5
|
import { assert } from "../asserts/module.f.js";
|
|
@@ -8,16 +8,15 @@ import { parse as jsonParse } from "../json/module.f.js";
|
|
|
8
8
|
import { unwrap } from "../types/result/module.f.js";
|
|
9
9
|
const hasRun = (cmd) => (gha) => Object.values(gha.jobs).some(job => job.steps.some(step => step.run?.includes(cmd)));
|
|
10
10
|
const hasRunInJob = (jobId, cmd) => (gha) => gha.jobs[jobId]?.steps.some(step => step.run?.includes(cmd)) ?? false;
|
|
11
|
-
const makeState = (rust) => ({
|
|
11
|
+
const makeState = (rust, packageJson) => ({
|
|
12
12
|
...emptyState,
|
|
13
13
|
root: {
|
|
14
14
|
'.github': { workflows: {} },
|
|
15
|
+
...(packageJson !== undefined ? { 'package.json': utf8(packageJson) } : {}),
|
|
15
16
|
...(rust ? { 'Cargo.toml': emptyVec } : {}),
|
|
16
17
|
},
|
|
17
18
|
});
|
|
18
|
-
const
|
|
19
|
-
const [state, result] = virtual(makeState(rust))(ci({ nodeExtra, denoExtra: [], bunExtra: [] }));
|
|
20
|
-
assert(result === 0, result);
|
|
19
|
+
const workflow = (state) => {
|
|
21
20
|
const dotGithub = state.root['.github'];
|
|
22
21
|
assert(typeof dotGithub === 'object', dotGithub);
|
|
23
22
|
const workflows = dotGithub['workflows'];
|
|
@@ -26,6 +25,16 @@ const run = (rust, nodeExtra = () => []) => {
|
|
|
26
25
|
assert(isVec(file), file);
|
|
27
26
|
return unwrap(parseGitHubAction(jsonParse(utf8ToString(file))));
|
|
28
27
|
};
|
|
28
|
+
const run = (rust, nodeExtra = () => []) => {
|
|
29
|
+
const [state, result] = virtual(makeState(rust))(ci({ nodeExtra, denoExtra: [], bunExtra: [] }));
|
|
30
|
+
assert(result === 0, result);
|
|
31
|
+
return workflow(state);
|
|
32
|
+
};
|
|
33
|
+
const runDefault = (packageJson) => {
|
|
34
|
+
const [state, result] = virtual(makeState(false, packageJson))(main());
|
|
35
|
+
assert(result === 0, result);
|
|
36
|
+
return workflow(state);
|
|
37
|
+
};
|
|
29
38
|
export const proof = {
|
|
30
39
|
rust: () => {
|
|
31
40
|
assert(hasRun('cargo')(run(true)), 'expected Rust steps');
|
|
@@ -52,4 +61,47 @@ export const proof = {
|
|
|
52
61
|
}
|
|
53
62
|
},
|
|
54
63
|
},
|
|
64
|
+
defaultSetup: {
|
|
65
|
+
functionalscriptDemo: () => {
|
|
66
|
+
const gha = runDefault('{"name":"functionalscript"}');
|
|
67
|
+
assert(hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'expected fjs demo compile');
|
|
68
|
+
assert(hasRun('fjs t')(gha), 'expected fjs self-test');
|
|
69
|
+
assert(hasRun('deno task fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'expected deno demo compile');
|
|
70
|
+
assert(hasRun('deno task fjs t')(gha), 'expected deno self-test');
|
|
71
|
+
assert(hasRun('bun ./fs/fjs/module.ts t')(gha), 'expected bun self-test');
|
|
72
|
+
},
|
|
73
|
+
otherPackageNoDemo: () => {
|
|
74
|
+
const gha = runDefault('{"name":"other-package"}');
|
|
75
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
76
|
+
assert(!hasRun('fjs t')(gha), 'unexpected fjs self-test');
|
|
77
|
+
assert(!hasRun('deno task fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected deno demo compile');
|
|
78
|
+
assert(!hasRun('deno task fjs t')(gha), 'unexpected deno self-test');
|
|
79
|
+
assert(!hasRun('bun ./fs/fjs/module.ts t')(gha), 'unexpected bun self-test');
|
|
80
|
+
},
|
|
81
|
+
uninstallPackageName: () => {
|
|
82
|
+
const gha = runDefault('{"name":"other-package"}');
|
|
83
|
+
assert(hasRun('npm uninstall other-package -g')(gha), 'expected package-specific uninstall');
|
|
84
|
+
assert(!hasRun('npm uninstall functionalscript -g')(gha), 'unexpected functionalscript uninstall');
|
|
85
|
+
},
|
|
86
|
+
malformedPackageJsonFallback: () => {
|
|
87
|
+
const gha = runDefault('{');
|
|
88
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
89
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
90
|
+
},
|
|
91
|
+
missingPackageJsonFallback: () => {
|
|
92
|
+
const gha = runDefault();
|
|
93
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
94
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
95
|
+
},
|
|
96
|
+
missingNameFallback: () => {
|
|
97
|
+
const gha = runDefault('{"version":"1.0.0"}');
|
|
98
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
99
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
100
|
+
},
|
|
101
|
+
nonObjectFallback: () => {
|
|
102
|
+
const gha = runDefault('[]');
|
|
103
|
+
assert(!hasRun('fjs compile issues/demo/data/tree.json _tree.f.js')(gha), 'unexpected fjs demo compile');
|
|
104
|
+
assert(hasRun('npm uninstall functionalscript -g')(gha), 'expected fallback uninstall');
|
|
105
|
+
},
|
|
106
|
+
},
|
|
55
107
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ValidationError } from '../../types/rtti/validate/module.f.ts';
|
|
2
|
+
import type { Ts } from '../../types/rtti/ts/module.f.ts';
|
|
3
|
+
import { type Result } from '../../types/result/module.f.ts';
|
|
4
|
+
export declare const packageJsonSchema: {
|
|
5
|
+
readonly name: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
6
|
+
readonly version: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
7
|
+
readonly scripts: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").Type1<"record", import("../../types/rtti/module.f.ts").String>, undefined]>;
|
|
8
|
+
};
|
|
9
|
+
export type PackageJson = Ts<typeof packageJsonSchema>;
|
|
10
|
+
export type JsonTextError = string | ValidationError;
|
|
11
|
+
export declare const validatePackageJson: import("../../types/rtti/common/module.f.ts").Validate<{
|
|
12
|
+
readonly name: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
13
|
+
readonly version: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").String, undefined]>;
|
|
14
|
+
readonly scripts: import("../../types/rtti/module.f.ts").Or<readonly [import("../../types/rtti/module.f.ts").Type1<"record", import("../../types/rtti/module.f.ts").String>, undefined]>;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const validatePackageJsonText: (text: string) => Result<PackageJson, JsonTextError>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { parse as jsonParse } from "../../json/parser/module.f.js";
|
|
2
|
+
import { tokenize as jsonTokenize } from "../../json/tokenizer/module.f.js";
|
|
3
|
+
import { stringToList } from "../../text/utf16/module.f.js";
|
|
4
|
+
import { option, record, string } from "../../types/rtti/module.f.js";
|
|
5
|
+
import { validate as rttiValidate } from "../../types/rtti/validate/module.f.js";
|
|
6
|
+
import { error, ok } from "../../types/result/module.f.js";
|
|
7
|
+
export const packageJsonSchema = {
|
|
8
|
+
name: option(string),
|
|
9
|
+
version: option(string),
|
|
10
|
+
scripts: option(record(string)),
|
|
11
|
+
};
|
|
12
|
+
export const validatePackageJson = rttiValidate(packageJsonSchema);
|
|
13
|
+
const parseJsonText = (text) => jsonParse(jsonTokenize(stringToList(text)));
|
|
14
|
+
export const validatePackageJsonText = (text) => {
|
|
15
|
+
const [t, v] = parseJsonText(text);
|
|
16
|
+
if (t === 'error') {
|
|
17
|
+
return error(v);
|
|
18
|
+
}
|
|
19
|
+
const [t2, v2] = validatePackageJson(v);
|
|
20
|
+
return t2 === 'ok' ? ok(v2) : error(v2);
|
|
21
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { assert } from "../../asserts/module.f.js";
|
|
2
|
+
import { unwrap } from "../../types/result/module.f.js";
|
|
3
|
+
import { validatePackageJson, validatePackageJsonText, } from "./module.f.js";
|
|
4
|
+
export const proof = {
|
|
5
|
+
parseMetadata: () => {
|
|
6
|
+
const result = unwrap(validatePackageJsonText('{"name":"x","version":"1.0.0","scripts":{"test":"node test.js"}}'));
|
|
7
|
+
assert(result.name === 'x', result);
|
|
8
|
+
assert(result.version === '1.0.0', result);
|
|
9
|
+
assert(result.scripts?.test === 'node test.js', result);
|
|
10
|
+
},
|
|
11
|
+
malformedJson: () => {
|
|
12
|
+
const result = validatePackageJsonText('{');
|
|
13
|
+
assert(result[0] === 'error', result);
|
|
14
|
+
},
|
|
15
|
+
validatePreservesOriginalObject: () => {
|
|
16
|
+
const object = { name: 'x', version: '1.0.0', private: true };
|
|
17
|
+
const metadata = unwrap(validatePackageJson(object));
|
|
18
|
+
assert(metadata.name === 'x', metadata);
|
|
19
|
+
assert(metadata.version === '1.0.0', metadata);
|
|
20
|
+
assert(Object.is(metadata, object), metadata);
|
|
21
|
+
assert(object.private === true, object);
|
|
22
|
+
},
|
|
23
|
+
};
|
|
@@ -7,21 +7,27 @@ import { utf8, utf8ToString } from "../../text/module.f.js";
|
|
|
7
7
|
import { begin, pure } from "../../effects/module.f.js";
|
|
8
8
|
import { all, readFile, writeFile } from "../../effects/node/module.f.js";
|
|
9
9
|
import { unwrap } from "../../types/result/module.f.js";
|
|
10
|
-
|
|
10
|
+
import { validatePackageJson } from "../package_json/module.f.js";
|
|
11
|
+
import { assert } from "../../asserts/module.f.js";
|
|
12
|
+
const { parse, stringify } = JSON;
|
|
11
13
|
const jsonFile = (jsonFile) => `${jsonFile}.json`;
|
|
12
14
|
const readJson = (name) => begin
|
|
13
15
|
.step(() => readFile(jsonFile(name)))
|
|
14
|
-
.step(v => pure(parse(utf8ToString(unwrap(v)))));
|
|
16
|
+
.step(v => pure(unwrap(validatePackageJson(parse(utf8ToString(unwrap(v)))))));
|
|
15
17
|
const writeVersion = (version) => (name) => begin
|
|
16
18
|
.step(() => readJson(name))
|
|
17
|
-
.step(json => writeFile(jsonFile(name), utf8(stringify({
|
|
19
|
+
.step((json) => writeFile(jsonFile(name), utf8(stringify({
|
|
18
20
|
...json,
|
|
19
21
|
version,
|
|
20
22
|
}, null, 2))));
|
|
23
|
+
const version = (p) => {
|
|
24
|
+
assert(p.version !== undefined, 'package.json version is missing');
|
|
25
|
+
return p.version;
|
|
26
|
+
};
|
|
21
27
|
export const updateVersion = begin
|
|
22
28
|
.step(() => readJson('package'))
|
|
23
29
|
.step(p => {
|
|
24
|
-
const w = writeVersion(p
|
|
30
|
+
const w = writeVersion(version(p));
|
|
25
31
|
return all(w('package'), w('deno'));
|
|
26
32
|
})
|
|
27
33
|
.step(() => pure(0));
|