fastscript 1.0.0 → 2.0.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +32 -7
  2. package/LICENSE +33 -21
  3. package/README.md +567 -73
  4. package/node_modules/@fastscript/core-private/BOUNDARY.json +15 -0
  5. package/node_modules/@fastscript/core-private/README.md +5 -0
  6. package/node_modules/@fastscript/core-private/package.json +34 -0
  7. package/node_modules/@fastscript/core-private/src/asset-optimizer.mjs +67 -0
  8. package/node_modules/@fastscript/core-private/src/audit-log.mjs +50 -0
  9. package/node_modules/@fastscript/core-private/src/auth-flows.mjs +29 -0
  10. package/node_modules/@fastscript/core-private/src/auth.mjs +115 -0
  11. package/node_modules/@fastscript/core-private/src/bench.mjs +45 -0
  12. package/node_modules/@fastscript/core-private/src/build.mjs +670 -0
  13. package/node_modules/@fastscript/core-private/src/cache.mjs +248 -0
  14. package/node_modules/@fastscript/core-private/src/check.mjs +22 -0
  15. package/node_modules/@fastscript/core-private/src/cli.mjs +95 -0
  16. package/node_modules/@fastscript/core-private/src/compat.mjs +128 -0
  17. package/node_modules/@fastscript/core-private/src/create.mjs +278 -0
  18. package/node_modules/@fastscript/core-private/src/csp.mjs +26 -0
  19. package/node_modules/@fastscript/core-private/src/db-cli.mjs +185 -0
  20. package/node_modules/@fastscript/core-private/src/db-postgres-collection.mjs +110 -0
  21. package/node_modules/@fastscript/core-private/src/db-postgres.mjs +40 -0
  22. package/node_modules/@fastscript/core-private/src/db.mjs +103 -0
  23. package/node_modules/@fastscript/core-private/src/deploy.mjs +662 -0
  24. package/node_modules/@fastscript/core-private/src/dev.mjs +5 -0
  25. package/node_modules/@fastscript/core-private/src/docs-search.mjs +35 -0
  26. package/node_modules/@fastscript/core-private/src/env.mjs +118 -0
  27. package/node_modules/@fastscript/core-private/src/export.mjs +83 -0
  28. package/node_modules/@fastscript/core-private/src/fs-diagnostics.mjs +70 -0
  29. package/node_modules/@fastscript/core-private/src/fs-error-codes.mjs +141 -0
  30. package/node_modules/@fastscript/core-private/src/fs-formatter.mjs +66 -0
  31. package/node_modules/@fastscript/core-private/src/fs-linter.mjs +274 -0
  32. package/node_modules/@fastscript/core-private/src/fs-normalize.mjs +91 -0
  33. package/node_modules/@fastscript/core-private/src/fs-parser.mjs +980 -0
  34. package/node_modules/@fastscript/core-private/src/generated/docs-search-index.mjs +3182 -0
  35. package/node_modules/@fastscript/core-private/src/i18n.mjs +25 -0
  36. package/node_modules/@fastscript/core-private/src/interop.mjs +16 -0
  37. package/node_modules/@fastscript/core-private/src/jobs.mjs +378 -0
  38. package/node_modules/@fastscript/core-private/src/logger.mjs +27 -0
  39. package/node_modules/@fastscript/core-private/src/metrics.mjs +45 -0
  40. package/node_modules/@fastscript/core-private/src/middleware.mjs +14 -0
  41. package/node_modules/@fastscript/core-private/src/migrate.mjs +81 -0
  42. package/node_modules/@fastscript/core-private/src/migration-wizard.mjs +16 -0
  43. package/node_modules/@fastscript/core-private/src/module-loader.mjs +46 -0
  44. package/node_modules/@fastscript/core-private/src/oauth-providers.mjs +103 -0
  45. package/node_modules/@fastscript/core-private/src/observability.mjs +21 -0
  46. package/node_modules/@fastscript/core-private/src/plugins.mjs +194 -0
  47. package/node_modules/@fastscript/core-private/src/retention.mjs +57 -0
  48. package/node_modules/@fastscript/core-private/src/routes.mjs +178 -0
  49. package/node_modules/@fastscript/core-private/src/scheduler.mjs +104 -0
  50. package/node_modules/@fastscript/core-private/src/security.mjs +233 -0
  51. package/node_modules/@fastscript/core-private/src/server-runtime.mjs +849 -0
  52. package/node_modules/@fastscript/core-private/src/serverless-handler.mjs +20 -0
  53. package/node_modules/@fastscript/core-private/src/session-policy.mjs +38 -0
  54. package/node_modules/@fastscript/core-private/src/start.mjs +10 -0
  55. package/node_modules/@fastscript/core-private/src/storage.mjs +155 -0
  56. package/node_modules/@fastscript/core-private/src/style-primitives.mjs +538 -0
  57. package/node_modules/@fastscript/core-private/src/style-system.mjs +461 -0
  58. package/node_modules/@fastscript/core-private/src/tenant.mjs +55 -0
  59. package/node_modules/@fastscript/core-private/src/typecheck.mjs +1464 -0
  60. package/node_modules/@fastscript/core-private/src/validate.mjs +22 -0
  61. package/node_modules/@fastscript/core-private/src/validation.mjs +88 -0
  62. package/node_modules/@fastscript/core-private/src/webhook.mjs +81 -0
  63. package/node_modules/@fastscript/core-private/src/worker.mjs +24 -0
  64. package/package.json +86 -13
  65. package/src/asset-optimizer.mjs +67 -0
  66. package/src/audit-log.mjs +50 -0
  67. package/src/auth.mjs +1 -115
  68. package/src/bench.mjs +20 -7
  69. package/src/build.mjs +1 -234
  70. package/src/cache.mjs +210 -20
  71. package/src/cli.mjs +29 -5
  72. package/src/compat.mjs +8 -10
  73. package/src/create.mjs +71 -17
  74. package/src/csp.mjs +26 -0
  75. package/src/db-cli.mjs +152 -8
  76. package/src/db-postgres-collection.mjs +110 -0
  77. package/src/deploy.mjs +1 -65
  78. package/src/docs-search.mjs +35 -0
  79. package/src/env.mjs +34 -5
  80. package/src/fs-diagnostics.mjs +70 -0
  81. package/src/fs-error-codes.mjs +126 -0
  82. package/src/fs-formatter.mjs +66 -0
  83. package/src/fs-linter.mjs +274 -0
  84. package/src/fs-normalize.mjs +21 -238
  85. package/src/fs-parser.mjs +1 -0
  86. package/src/generated/docs-search-index.mjs +3220 -0
  87. package/src/i18n.mjs +25 -0
  88. package/src/jobs.mjs +283 -32
  89. package/src/metrics.mjs +45 -0
  90. package/src/migration-wizard.mjs +16 -0
  91. package/src/module-loader.mjs +11 -12
  92. package/src/oauth-providers.mjs +103 -0
  93. package/src/plugins.mjs +194 -0
  94. package/src/retention.mjs +57 -0
  95. package/src/routes.mjs +178 -0
  96. package/src/scheduler.mjs +104 -0
  97. package/src/security.mjs +197 -19
  98. package/src/server-runtime.mjs +1 -339
  99. package/src/serverless-handler.mjs +20 -0
  100. package/src/session-policy.mjs +38 -0
  101. package/src/storage.mjs +1 -56
  102. package/src/style-system.mjs +461 -0
  103. package/src/tenant.mjs +55 -0
  104. package/src/typecheck.mjs +1 -0
  105. package/src/validate.mjs +5 -1
  106. package/src/validation.mjs +14 -5
  107. package/src/webhook.mjs +1 -71
  108. package/src/worker.mjs +23 -4
  109. package/src/language-spec.mjs +0 -58
package/src/webhook.mjs CHANGED
@@ -1,71 +1 @@
1
- import { createHmac, timingSafeEqual } from "node:crypto";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
- import { join, resolve } from "node:path";
4
-
5
- export async function readRawBody(req) {
6
- const chunks = [];
7
- for await (const chunk of req) chunks.push(Buffer.from(chunk));
8
- return Buffer.concat(chunks);
9
- }
10
-
11
- export function signPayload(payload, secret, algo = "sha256") {
12
- const mac = createHmac(algo, secret).update(payload).digest("hex");
13
- return `${algo}=${mac}`;
14
- }
15
-
16
- export function verifySignature(payload, header, secret, algo = "sha256") {
17
- if (!header || typeof header !== "string") return false;
18
- const expected = signPayload(payload, secret, algo);
19
- const a = Buffer.from(expected);
20
- const b = Buffer.from(header);
21
- if (a.length !== b.length) return false;
22
- return timingSafeEqual(a, b);
23
- }
24
-
25
- export function isReplay(tsSeconds, maxSkewSec = 300) {
26
- const ts = Number(tsSeconds);
27
- if (!Number.isFinite(ts)) return true;
28
- const now = Math.floor(Date.now() / 1000);
29
- return Math.abs(now - ts) > maxSkewSec;
30
- }
31
-
32
- function replayStore({ dir = ".fastscript", ttlSec = 600 } = {}) {
33
- const root = resolve(dir);
34
- mkdirSync(root, { recursive: true });
35
- const file = join(root, "webhook-replay.json");
36
- let state = { seen: {} };
37
- if (existsSync(file)) {
38
- try { state = JSON.parse(readFileSync(file, "utf8")); } catch {}
39
- }
40
- function persist() {
41
- writeFileSync(file, JSON.stringify(state, null, 2), "utf8");
42
- }
43
- return {
44
- has(id) {
45
- const now = Date.now();
46
- for (const [k, exp] of Object.entries(state.seen)) if (exp < now) delete state.seen[k];
47
- persist();
48
- return Boolean(state.seen[id]);
49
- },
50
- add(id) {
51
- state.seen[id] = Date.now() + ttlSec * 1000;
52
- persist();
53
- },
54
- };
55
- }
56
-
57
- export async function verifyWebhookRequest(req, { secret, signatureHeader = "x-signature", timestampHeader = "x-timestamp", idHeader = "x-event-id", maxSkewSec = 300, replayDir = ".fastscript" } = {}) {
58
- const raw = await readRawBody(req);
59
- const sig = req.headers[signatureHeader];
60
- const ts = req.headers[timestampHeader];
61
- const eventId = req.headers[idHeader];
62
- const id = Array.isArray(eventId) ? eventId[0] : eventId;
63
- if (isReplay(ts, maxSkewSec)) return { ok: false, reason: "replay_window" };
64
- if (!verifySignature(raw, Array.isArray(sig) ? sig[0] : sig, secret)) return { ok: false, reason: "bad_signature" };
65
- if (id) {
66
- const store = replayStore({ dir: replayDir, ttlSec: Math.max(maxSkewSec, 600) });
67
- if (store.has(id)) return { ok: false, reason: "duplicate_event" };
68
- store.add(id);
69
- }
70
- return { ok: true, raw };
71
- }
1
+ export * from "@fastscript/core-private/webhook";
package/src/worker.mjs CHANGED
@@ -1,5 +1,24 @@
1
- import { runWorker } from "./jobs.mjs";
1
+ import { replayDeadLetter, runWorker } from "./jobs.mjs";
2
2
 
3
- export async function runWorkerCommand() {
4
- await runWorker({ dir: ".fastscript", pollMs: Number(process.env.WORKER_POLL_MS || 350) });
5
- }
3
+ export async function runWorkerCommand(args = []) {
4
+ if (args[0] === "replay-dead-letter") {
5
+ const limitArg = args.indexOf("--limit");
6
+ const nameArg = args.indexOf("--name");
7
+ const limit = limitArg >= 0 ? Number(args[limitArg + 1] || 20) : 20;
8
+ const name = nameArg >= 0 ? args[nameArg + 1] || null : null;
9
+ const replayed = await replayDeadLetter({
10
+ dir: ".fastscript",
11
+ limit,
12
+ name,
13
+ driver: process.env.JOBS_DRIVER || "file",
14
+ });
15
+ console.log(`dead-letter replayed: ${replayed.length}`);
16
+ return;
17
+ }
18
+
19
+ await runWorker({
20
+ dir: ".fastscript",
21
+ pollMs: Number(process.env.WORKER_POLL_MS || 350),
22
+ driver: process.env.JOBS_DRIVER || "file",
23
+ });
24
+ }
@@ -1,58 +0,0 @@
1
- import {
2
- analyzeFastScriptSource,
3
- createFastScriptDiagnosticError,
4
- formatFastScriptDiagnostics,
5
- normalizeFastScriptWithTelemetry,
6
- } from "./fs-normalize.mjs";
7
-
8
- export const FASTSCRIPT_LANGUAGE_SPEC_VERSION = "v1.0";
9
-
10
- export const FASTSCRIPT_LANGUAGE_SPEC = Object.freeze({
11
- version: FASTSCRIPT_LANGUAGE_SPEC_VERSION,
12
- goals: [
13
- "Lenient syntax that compiles to JavaScript quickly",
14
- "JS ecosystem compatibility first",
15
- ".fs primary surface with .js zero-friction support",
16
- ],
17
- sugar: [
18
- "~name = value -> let name = value",
19
- "state name = value -> let name = value",
20
- "fn add(a, b) -> function add(a, b)",
21
- ],
22
- diagnostics: {
23
- errors: ["FS_EMPTY_IMPORT"],
24
- warnings: [
25
- "FS_BAD_REACTIVE",
26
- "FS_BAD_STATE",
27
- "FS_BAD_FN",
28
- "FS_DUP_STATE",
29
- "FS_RELATIVE_JS_IMPORT",
30
- ],
31
- },
32
- });
33
-
34
- export function getLanguageSpec() {
35
- return FASTSCRIPT_LANGUAGE_SPEC;
36
- }
37
-
38
- export function inspectFastScriptSource(source, { filename = "input.fs" } = {}) {
39
- const diagnostics = analyzeFastScriptSource(source, { filename });
40
- const printable = formatFastScriptDiagnostics(diagnostics, { filename, includeWarnings: true });
41
- return {
42
- ok: diagnostics.every((diag) => diag.severity !== "error"),
43
- diagnostics,
44
- printable,
45
- };
46
- }
47
-
48
- export function compileFastScriptSource(source, { filename = "input.fs", strict = false } = {}) {
49
- return normalizeFastScriptWithTelemetry(source, { filename, strict });
50
- }
51
-
52
- export function assertFastScriptSource(source, { filename = "input.fs" } = {}) {
53
- const diagnostics = analyzeFastScriptSource(source, { filename });
54
- const errors = diagnostics.filter((diag) => diag.severity === "error");
55
- if (errors.length > 0) throw createFastScriptDiagnosticError(errors, { filename, includeWarnings: false });
56
- return diagnostics;
57
- }
58
-