@nudojs/cli 0.2.1 → 0.3.1

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.
Files changed (64) hide show
  1. package/dist/{chunk-3HCPXPEW.js → chunk-YDM4HHQ4.js} +1783 -1421
  2. package/dist/evaluator-api.d.ts +12 -1
  3. package/dist/evaluator-api.js +52 -2
  4. package/dist/index.d.ts +1 -2
  5. package/dist/index.js +366 -3572
  6. package/package.json +23 -11
  7. package/CHANGELOG.md +0 -41
  8. package/examples/real-world.js +0 -66
  9. package/examples/validate-real-world.ts +0 -160
  10. package/src/__tests__/builtin-advanced.test.ts +0 -292
  11. package/src/__tests__/builtin-api.test.ts +0 -308
  12. package/src/__tests__/builtin-functions.test.ts +0 -313
  13. package/src/__tests__/builtin-map.test.ts +0 -129
  14. package/src/__tests__/builtin-promise.test.ts +0 -150
  15. package/src/__tests__/builtin-regexp.test.ts +0 -133
  16. package/src/__tests__/builtin-set.test.ts +0 -163
  17. package/src/__tests__/builtin-url.test.ts +0 -256
  18. package/src/__tests__/builtin-web.test.ts +0 -340
  19. package/src/__tests__/combination-scenarios.test.ts +0 -384
  20. package/src/__tests__/edge-cases.test.ts +0 -749
  21. package/src/__tests__/evaluator-loops.test.ts +0 -283
  22. package/src/__tests__/evaluator-nullish-coalescing.test.ts +0 -86
  23. package/src/__tests__/evaluator-optional-chaining.test.ts +0 -37
  24. package/src/__tests__/evaluator-phase2.test.ts +0 -564
  25. package/src/__tests__/evaluator-phase3.test.ts +0 -864
  26. package/src/__tests__/evaluator-refined.test.ts +0 -121
  27. package/src/__tests__/evaluator-string-methods.test.ts +0 -151
  28. package/src/__tests__/evaluator.test.ts +0 -943
  29. package/src/__tests__/mock-arrow-function.test.ts +0 -169
  30. package/src/__tests__/mock-comparison.test.ts +0 -221
  31. package/src/__tests__/mock-comprehensive.test.ts +0 -250
  32. package/src/__tests__/mock-final-integration.test.ts +0 -263
  33. package/src/__tests__/mock-helpers.test.ts +0 -174
  34. package/src/__tests__/mock-realworld.test.ts +0 -191
  35. package/src/__tests__/mock-rest-debug.test.ts +0 -110
  36. package/src/__tests__/mock-rest-edge.test.ts +0 -176
  37. package/src/__tests__/mock-sinon-runtime.test.ts +0 -168
  38. package/src/__tests__/narrowing-discriminated.test.ts +0 -35
  39. package/src/__tests__/narrowing-in-operator.test.ts +0 -56
  40. package/src/__tests__/narrowing-switch.test.ts +0 -56
  41. package/src/__tests__/narrowing-truthiness.test.ts +0 -52
  42. package/src/__tests__/narrowing.test.ts +0 -82
  43. package/src/__tests__/nudo-mock-syntax.test.ts +0 -245
  44. package/src/__tests__/realworld-patterns.test.ts +0 -430
  45. package/src/__tests__/syntax-sugar.test.ts +0 -345
  46. package/src/builtins/builtin-intl.ts +0 -17
  47. package/src/builtins/builtin-map.ts +0 -174
  48. package/src/builtins/builtin-promise.ts +0 -116
  49. package/src/builtins/builtin-reflect.ts +0 -30
  50. package/src/builtins/builtin-regexp.ts +0 -34
  51. package/src/builtins/builtin-set.ts +0 -131
  52. package/src/builtins/builtin-symbol.ts +0 -16
  53. package/src/builtins/builtin-url.ts +0 -58
  54. package/src/builtins/builtin-weak.ts +0 -22
  55. package/src/builtins/builtin-web.ts +0 -111
  56. package/src/builtins/index.ts +0 -61
  57. package/src/config.ts +0 -32
  58. package/src/env-loader.ts +0 -174
  59. package/src/evaluator-api.ts +0 -36
  60. package/src/evaluator.ts +0 -5623
  61. package/src/index.ts +0 -931
  62. package/src/narrowing.ts +0 -537
  63. package/src/resolve-npm.ts +0 -63
  64. package/tsconfig.json +0 -9
@@ -1,121 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { T, typeValueEquals, typeValueToString, isSubtypeOf } from "@nudojs/core";
3
- import { isTemplate, getTemplateParts, isRange, getRangeMeta } from "@nudojs/core";
4
- import { evaluate, evaluateProgram } from "../evaluator.ts";
5
- import { createEnvironment } from "@nudojs/core";
6
- import { parse } from "@nudojs/parser";
7
-
8
- function evalExpr(code: string): import("@nudojs/core").TypeValue {
9
- const ast = parse(code);
10
- const env = createEnvironment();
11
- return evaluateProgram(ast, env);
12
- }
13
-
14
- function evalWithBindings(code: string, bindings: Record<string, import("@nudojs/core").TypeValue>): import("@nudojs/core").TypeValue {
15
- const ast = parse(code);
16
- const env = createEnvironment();
17
- for (const [k, v] of Object.entries(bindings)) {
18
- env.bind(k, v);
19
- }
20
- return evaluateProgram(ast, env);
21
- }
22
-
23
- describe("Template Literal Evaluation", () => {
24
- it("all-literal template produces literal", () => {
25
- const result = evalExpr("`hello world`");
26
- expect(typeValueEquals(result, T.literal("hello world"))).toBe(true);
27
- });
28
-
29
- it("template with abstract expression produces template type", () => {
30
- const result = evalWithBindings("`xy${x}`", { x: T.string });
31
- expect(isTemplate(result)).toBe(true);
32
- expect(typeValueToString(result)).toBe("`xy${string}`");
33
- });
34
-
35
- it("template with multiple parts", () => {
36
- const result = evalWithBindings("`${x}!`", { x: T.string });
37
- expect(isTemplate(result)).toBe(true);
38
- expect(typeValueToString(result)).toBe("`${string}!`");
39
- });
40
-
41
- it("string concatenation with + produces template", () => {
42
- const result = evalWithBindings('"xy" + x', { x: T.string });
43
- expect(isTemplate(result)).toBe(true);
44
- expect(typeValueToString(result)).toBe("`xy${string}`");
45
- });
46
-
47
- it("chained concatenation produces template", () => {
48
- const result = evalWithBindings('"x" + x + "!"', { x: T.string });
49
- expect(isTemplate(result)).toBe(true);
50
- expect(typeValueToString(result)).toBe("`x${string}!`");
51
- });
52
- });
53
-
54
- describe("Template Method Dispatch", () => {
55
- it("startsWith on template with known prefix returns true", () => {
56
- const result = evalWithBindings(
57
- 'const s = "xy" + x; s.startsWith("x")',
58
- { x: T.string },
59
- );
60
- // The evaluateMethodCall should dispatch to template's startsWith
61
- // and return T.literal(true)
62
- // Note: this requires string method support in evaluateMethodCall
63
- // which we add in 6.1. For now, refined dispatch handles it.
64
- if (result.kind === "literal") {
65
- expect(result.value).toBe(true);
66
- }
67
- });
68
- });
69
-
70
- describe("Range Narrowing", () => {
71
- it("x >= 0 narrows to range in true branch", () => {
72
- const code = `
73
- function f(x) {
74
- if (x >= 0) {
75
- return x;
76
- }
77
- return x;
78
- }
79
- `;
80
- const ast = parse(code);
81
- const env = createEnvironment();
82
- evaluateProgram(ast, env);
83
- const fn = env.lookup("f");
84
- expect(fn.kind).toBe("function");
85
- });
86
-
87
- it("range comparison produces correct results", () => {
88
- const result = evalWithBindings(
89
- 'const r = x >= 0 ? x : 0; r',
90
- { x: T.number },
91
- );
92
- // In the true branch, x is narrowed to range(min:0)
93
- // In the false branch, result is T.literal(0)
94
- // Union of both
95
- expect(result).toBeDefined();
96
- });
97
- });
98
-
99
- describe("User-defined Refined Types", () => {
100
- it("refined type with custom ops", () => {
101
- const odd = T.refine(T.number, {
102
- name: "odd",
103
- meta: {},
104
- ops: {
105
- "%"(self, other) {
106
- if (other.kind === "literal" && other.value === 2) return T.literal(1);
107
- return undefined;
108
- },
109
- },
110
- });
111
-
112
- const result = evalWithBindings("x % 2", { x: odd });
113
- expect(typeValueEquals(result, T.literal(1))).toBe(true);
114
- });
115
-
116
- it("refined type falls back to base for undefined ops", () => {
117
- const odd = T.refine(T.number, { name: "odd", meta: {} });
118
- const result = evalWithBindings("x + 1", { x: odd });
119
- expect(typeValueEquals(result, T.number)).toBe(true);
120
- });
121
- });
@@ -1,151 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { T, typeValueEquals, createEnvironment } from "@nudojs/core";
3
- import { evaluateProgram } from "../evaluator.ts";
4
- import { parse } from "@nudojs/parser";
5
- import type { TypeValue } from "@nudojs/core";
6
-
7
- function evalExpr(code: string): TypeValue {
8
- const ast = parse(code);
9
- const env = createEnvironment();
10
- return evaluateProgram(ast, env);
11
- }
12
-
13
- function evalWith(code: string, bindings: Record<string, TypeValue>): TypeValue {
14
- const ast = parse(code);
15
- const env = createEnvironment();
16
- for (const [k, v] of Object.entries(bindings)) env.bind(k, v);
17
- return evaluateProgram(ast, env);
18
- }
19
-
20
- describe("String methods - literal receiver", () => {
21
- it("toUpperCase", () => {
22
- expect(typeValueEquals(evalExpr('"hello".toUpperCase()'), T.literal("HELLO"))).toBe(true);
23
- });
24
-
25
- it("toLowerCase", () => {
26
- expect(typeValueEquals(evalExpr('"HELLO".toLowerCase()'), T.literal("hello"))).toBe(true);
27
- });
28
-
29
- it("trim", () => {
30
- expect(typeValueEquals(evalExpr('" hi ".trim()'), T.literal("hi"))).toBe(true);
31
- });
32
-
33
- it("trimStart", () => {
34
- expect(typeValueEquals(evalExpr('" hi".trimStart()'), T.literal("hi"))).toBe(true);
35
- });
36
-
37
- it("trimEnd", () => {
38
- expect(typeValueEquals(evalExpr('"hi ".trimEnd()'), T.literal("hi"))).toBe(true);
39
- });
40
-
41
- it("charAt", () => {
42
- expect(typeValueEquals(evalExpr('"abc".charAt(1)'), T.literal("b"))).toBe(true);
43
- });
44
-
45
- it("charCodeAt", () => {
46
- expect(typeValueEquals(evalExpr('"A".charCodeAt(0)'), T.literal(65))).toBe(true);
47
- });
48
-
49
- it("at", () => {
50
- expect(typeValueEquals(evalExpr('"abc".at(-1)'), T.literal("c"))).toBe(true);
51
- });
52
-
53
- it("startsWith", () => {
54
- expect(typeValueEquals(evalExpr('"hello".startsWith("he")'), T.literal(true))).toBe(true);
55
- expect(typeValueEquals(evalExpr('"hello".startsWith("lo")'), T.literal(false))).toBe(true);
56
- });
57
-
58
- it("endsWith", () => {
59
- expect(typeValueEquals(evalExpr('"hello".endsWith("lo")'), T.literal(true))).toBe(true);
60
- expect(typeValueEquals(evalExpr('"hello".endsWith("he")'), T.literal(false))).toBe(true);
61
- });
62
-
63
- it("includes", () => {
64
- expect(typeValueEquals(evalExpr('"hello".includes("ell")'), T.literal(true))).toBe(true);
65
- expect(typeValueEquals(evalExpr('"hello".includes("xyz")'), T.literal(false))).toBe(true);
66
- });
67
-
68
- it("indexOf", () => {
69
- expect(typeValueEquals(evalExpr('"hello".indexOf("l")'), T.literal(2))).toBe(true);
70
- expect(typeValueEquals(evalExpr('"hello".indexOf("z")'), T.literal(-1))).toBe(true);
71
- });
72
-
73
- it("lastIndexOf", () => {
74
- expect(typeValueEquals(evalExpr('"hello".lastIndexOf("l")'), T.literal(3))).toBe(true);
75
- });
76
-
77
- it("slice", () => {
78
- expect(typeValueEquals(evalExpr('"hello".slice(1, 3)'), T.literal("el"))).toBe(true);
79
- expect(typeValueEquals(evalExpr('"hello".slice(2)'), T.literal("llo"))).toBe(true);
80
- });
81
-
82
- it("substring", () => {
83
- expect(typeValueEquals(evalExpr('"hello".substring(1, 4)'), T.literal("ell"))).toBe(true);
84
- });
85
-
86
- it("split", () => {
87
- const result = evalExpr('"a,b,c".split(",")');
88
- expect(result.kind).toBe("tuple");
89
- if (result.kind === "tuple") {
90
- expect(result.elements.length).toBe(3);
91
- expect(typeValueEquals(result.elements[0], T.literal("a"))).toBe(true);
92
- expect(typeValueEquals(result.elements[1], T.literal("b"))).toBe(true);
93
- expect(typeValueEquals(result.elements[2], T.literal("c"))).toBe(true);
94
- }
95
- });
96
-
97
- it("replace", () => {
98
- expect(typeValueEquals(evalExpr('"hello".replace("l", "r")'), T.literal("herlo"))).toBe(true);
99
- });
100
-
101
- it("replaceAll", () => {
102
- expect(typeValueEquals(evalExpr('"hello".replaceAll("l", "r")'), T.literal("herro"))).toBe(true);
103
- });
104
-
105
- it("repeat", () => {
106
- expect(typeValueEquals(evalExpr('"ab".repeat(3)'), T.literal("ababab"))).toBe(true);
107
- });
108
-
109
- it("padStart", () => {
110
- expect(typeValueEquals(evalExpr('"5".padStart(3, "0")'), T.literal("005"))).toBe(true);
111
- });
112
-
113
- it("padEnd", () => {
114
- expect(typeValueEquals(evalExpr('"5".padEnd(3, "0")'), T.literal("500"))).toBe(true);
115
- });
116
- });
117
-
118
- describe("String methods - abstract receiver", () => {
119
- it("toUpperCase returns string", () => {
120
- const result = evalWith("x.toUpperCase()", { x: T.string });
121
- expect(typeValueEquals(result, T.string)).toBe(true);
122
- });
123
-
124
- it("startsWith returns boolean", () => {
125
- const result = evalWith('x.startsWith("a")', { x: T.string });
126
- expect(typeValueEquals(result, T.boolean)).toBe(true);
127
- });
128
-
129
- it("indexOf returns number", () => {
130
- const result = evalWith('x.indexOf("a")', { x: T.string });
131
- expect(typeValueEquals(result, T.number)).toBe(true);
132
- });
133
-
134
- it("split returns string[]", () => {
135
- const result = evalWith('x.split(",")', { x: T.string });
136
- expect(result.kind).toBe("array");
137
- if (result.kind === "array") {
138
- expect(typeValueEquals(result.element, T.string)).toBe(true);
139
- }
140
- });
141
-
142
- it("charAt returns string", () => {
143
- const result = evalWith("x.charAt(0)", { x: T.string });
144
- expect(typeValueEquals(result, T.string)).toBe(true);
145
- });
146
-
147
- it("slice returns string", () => {
148
- const result = evalWith("x.slice(1)", { x: T.string });
149
- expect(typeValueEquals(result, T.string)).toBe(true);
150
- });
151
- });