rastack 0.0.16

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 (140) hide show
  1. package/CHANGELOG.md +43013 -0
  2. package/dist/.prettierrc +7 -0
  3. package/dist/compile/analyze.d.ts +12 -0
  4. package/dist/compile/analyze.js +233 -0
  5. package/dist/compile/index.d.ts +19 -0
  6. package/dist/compile/index.js +107 -0
  7. package/dist/compile/manifest.d.ts +4 -0
  8. package/dist/compile/manifest.js +12 -0
  9. package/dist/compile/model.d.ts +54 -0
  10. package/dist/compile/model.js +7 -0
  11. package/dist/compile/openapi.d.ts +11 -0
  12. package/dist/compile/openapi.js +233 -0
  13. package/dist/compile/program.d.ts +10 -0
  14. package/dist/compile/program.js +61 -0
  15. package/dist/csv-schema.d.ts +28 -0
  16. package/dist/csv-schema.js +162 -0
  17. package/dist/define/index.d.ts +117 -0
  18. package/dist/define/index.js +74 -0
  19. package/dist/entity-generation/delete-method.d.ts +1 -0
  20. package/dist/entity-generation/delete-method.js +31 -0
  21. package/dist/entity-generation/form.d.ts +13 -0
  22. package/dist/entity-generation/form.js +136 -0
  23. package/dist/entity-generation/get-method.d.ts +1 -0
  24. package/dist/entity-generation/get-method.js +67 -0
  25. package/dist/entity-generation/imports.d.ts +5 -0
  26. package/dist/entity-generation/imports.js +91 -0
  27. package/dist/entity-generation/sync-method.d.ts +30 -0
  28. package/dist/entity-generation/sync-method.js +158 -0
  29. package/dist/entity-generation/update-method.d.ts +1 -0
  30. package/dist/entity-generation/update-method.js +29 -0
  31. package/dist/index.d.ts +2 -0
  32. package/dist/index.js +53 -0
  33. package/dist/rad-compile.d.ts +11 -0
  34. package/dist/rad-compile.js +82 -0
  35. package/dist/rad-wasm-build.d.ts +14 -0
  36. package/dist/rad-wasm-build.js +74 -0
  37. package/dist/rad.d.ts +17 -0
  38. package/dist/rad.js +88 -0
  39. package/dist/scan.d.ts +12 -0
  40. package/dist/scan.js +79 -0
  41. package/dist/schema/camel-to-pastel.d.ts +1 -0
  42. package/dist/schema/camel-to-pastel.js +7 -0
  43. package/dist/schema/capitalise-first-letter.d.ts +1 -0
  44. package/dist/schema/capitalise-first-letter.js +7 -0
  45. package/dist/schema/extract-response.d.ts +2 -0
  46. package/dist/schema/extract-response.js +30 -0
  47. package/dist/schema/fetch-schema.d.ts +7 -0
  48. package/dist/schema/fetch-schema.js +23 -0
  49. package/dist/schema/remove-non-model-paths.d.ts +2 -0
  50. package/dist/schema/remove-non-model-paths.js +15 -0
  51. package/dist/schema/to-camel-case.d.ts +1 -0
  52. package/dist/schema/to-camel-case.js +11 -0
  53. package/dist/schema/to-pastel-case.d.ts +1 -0
  54. package/dist/schema/to-pastel-case.js +10 -0
  55. package/dist/schema-convert.d.ts +1 -0
  56. package/dist/schema-convert.js +63 -0
  57. package/dist/schema-entities.d.ts +14 -0
  58. package/dist/schema-entities.js +293 -0
  59. package/dist/schema-fetch.d.ts +1 -0
  60. package/dist/schema-fetch.js +81 -0
  61. package/dist/schema-full.d.ts +1 -0
  62. package/dist/schema-full.js +45 -0
  63. package/dist/schema-index.d.ts +1 -0
  64. package/dist/schema-index.js +34 -0
  65. package/dist/schema-params.d.ts +1 -0
  66. package/dist/schema-params.js +100 -0
  67. package/dist/seed.d.ts +17 -0
  68. package/dist/seed.js +252 -0
  69. package/hooks/form/form.ts +207 -0
  70. package/hooks/form/index.ts +8 -0
  71. package/hooks/form/interfaces.ts +217 -0
  72. package/hooks/form/structure.ts +39 -0
  73. package/hooks/form/validate-schema.ts +49 -0
  74. package/hooks/index.ts +3 -0
  75. package/hooks/query/api.ts +42 -0
  76. package/hooks/query/delete.ts +45 -0
  77. package/hooks/query/fetch.ts +48 -0
  78. package/hooks/query/index.ts +21 -0
  79. package/hooks/query/interfaces.ts +111 -0
  80. package/hooks/query/list.ts +286 -0
  81. package/hooks/query/update.ts +88 -0
  82. package/hooks/query/url.ts +31 -0
  83. package/hooks/real-time/index.ts +1 -0
  84. package/hooks/real-time/pusher.ts +43 -0
  85. package/jest.config.cjs +6 -0
  86. package/package.json +57 -0
  87. package/provider/index.ts +13 -0
  88. package/provider/provider.tsx +187 -0
  89. package/provider/types.ts +114 -0
  90. package/provider/warehouse.ts +167 -0
  91. package/provider/wasm.ts +124 -0
  92. package/runtime.ts +3 -0
  93. package/src/.prettierrc +7 -0
  94. package/src/compile/analyze.ts +224 -0
  95. package/src/compile/index.ts +86 -0
  96. package/src/compile/manifest.ts +10 -0
  97. package/src/compile/model.ts +69 -0
  98. package/src/compile/openapi.ts +266 -0
  99. package/src/compile/program.ts +40 -0
  100. package/src/csv-schema.ts +187 -0
  101. package/src/define/index.ts +162 -0
  102. package/src/entity-generation/delete-method.ts +37 -0
  103. package/src/entity-generation/form.ts +169 -0
  104. package/src/entity-generation/get-method.ts +80 -0
  105. package/src/entity-generation/imports.ts +110 -0
  106. package/src/entity-generation/sync-method.ts +222 -0
  107. package/src/entity-generation/update-method.ts +38 -0
  108. package/src/index.ts +77 -0
  109. package/src/rad-compile.ts +88 -0
  110. package/src/rad-wasm-build.ts +102 -0
  111. package/src/rad.ts +101 -0
  112. package/src/scan.ts +89 -0
  113. package/src/schema/camel-to-pastel.ts +3 -0
  114. package/src/schema/capitalise-first-letter.ts +3 -0
  115. package/src/schema/extract-response.ts +38 -0
  116. package/src/schema/fetch-schema.ts +12 -0
  117. package/src/schema/remove-non-model-paths.ts +13 -0
  118. package/src/schema/to-camel-case.ts +7 -0
  119. package/src/schema/to-pastel-case.ts +6 -0
  120. package/src/schema-convert.ts +61 -0
  121. package/src/schema-entities.ts +401 -0
  122. package/src/schema-fetch.ts +82 -0
  123. package/src/schema-full.ts +38 -0
  124. package/src/schema-index.ts +29 -0
  125. package/src/schema-params.ts +116 -0
  126. package/src/seed.ts +297 -0
  127. package/sync/engine.ts +392 -0
  128. package/sync/hooks.ts +450 -0
  129. package/sync/index.ts +8 -0
  130. package/sync/persistence.ts +237 -0
  131. package/sync/provider.tsx +91 -0
  132. package/sync/registry.ts +36 -0
  133. package/sync/store.ts +126 -0
  134. package/sync/transactions.ts +300 -0
  135. package/sync/types.ts +94 -0
  136. package/test/compile.spec.ts +192 -0
  137. package/test/csv-schema.spec.ts +143 -0
  138. package/test/schema-entities.spec.ts +688 -0
  139. package/tsconfig.json +24 -0
  140. package/types.ts +19 -0
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * `rad compile | check | list | urls` — the TypeScript-first replacement for the
5
+ * old Django `manage.py rastack` command.
6
+ *
7
+ * rad compile [resourcesDir] [outDir] defs → schema.rad.json + openapi.json
8
+ * rad check [resourcesDir] validate the resource graph (exit != 0 on error)
9
+ * rad list [resourcesDir] print every resource + its fields/relations
10
+ * rad urls [resourcesDir] print the generated /api/{app}/v1/{model}/ routes
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const compile_1 = require("./compile");
14
+ const DEFAULT_RESOURCES = "resources";
15
+ const DEFAULT_OUT = ".rad";
16
+ function main(argv) {
17
+ const [sub, ...rest] = argv;
18
+ switch (sub) {
19
+ case "compile": {
20
+ const resourcesDir = rest[0] || DEFAULT_RESOURCES;
21
+ const outDir = rest[1] || DEFAULT_OUT;
22
+ const result = (0, compile_1.compile)(resourcesDir, outDir);
23
+ console.log(`✓ compiled ${result.manifest.resources.length} resource(s) → ${result.files.join(", ")}`);
24
+ break;
25
+ }
26
+ case "check": {
27
+ const resources = (0, compile_1.analyzeResources)(rest[0] || DEFAULT_RESOURCES);
28
+ const errors = (0, compile_1.collisions)(resources);
29
+ if (errors.length) {
30
+ for (const e of errors)
31
+ console.error(` ✗ ${e}`);
32
+ console.error(`${errors.length} error(s) found.`);
33
+ process.exit(1);
34
+ }
35
+ console.log(`✓ ${resources.length} resource(s): no collisions.`);
36
+ break;
37
+ }
38
+ case "list": {
39
+ const resources = (0, compile_1.analyzeResources)(rest[0] || DEFAULT_RESOURCES);
40
+ if (!resources.length) {
41
+ console.log("No resources found.");
42
+ break;
43
+ }
44
+ for (const r of resources) {
45
+ console.log(`${r.app}.${r.model}`);
46
+ for (const f of r.fields) {
47
+ const rel = f.relation ? ` → ${f.relation.app}.${f.relation.model}` : "";
48
+ console.log(` ${f.name}: ${f.type}${rel}`);
49
+ }
50
+ if (r.sync) {
51
+ const flags = [
52
+ r.sync.mode,
53
+ r.sync.load === "lazy" ? "lazy" : "",
54
+ r.sync.clientIds ? "client-ids" : "",
55
+ r.sync.confirmed ? `confirmed: ${r.sync.confirmed.join(",")}` : "",
56
+ ]
57
+ .filter(Boolean)
58
+ .join(", ");
59
+ console.log(` sync: ${flags}`);
60
+ }
61
+ }
62
+ break;
63
+ }
64
+ case "urls": {
65
+ const resources = (0, compile_1.analyzeResources)(rest[0] || DEFAULT_RESOURCES);
66
+ for (const url of (0, compile_1.urlsFor)(resources))
67
+ console.log(url);
68
+ break;
69
+ }
70
+ default:
71
+ console.error(`Unknown compile subcommand: "${sub}"\n\n` +
72
+ `Usage:\n` +
73
+ ` rad compile [resourcesDir] [outDir]\n` +
74
+ ` rad check [resourcesDir]\n` +
75
+ ` rad list [resourcesDir]\n` +
76
+ ` rad urls [resourcesDir]\n`);
77
+ process.exit(1);
78
+ }
79
+ }
80
+ if (require.main === module) {
81
+ main(process.argv.slice(2));
82
+ }
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `rad wasm` — compile the Rust API to WebAssembly for in-browser local dev.
4
+ *
5
+ * Pipeline:
6
+ * 1. cargo build -p rad-wasm --release --target wasm32-unknown-unknown
7
+ * 2. wasm-bindgen --target web → stack/wasm/rad_wasm.js + rad_wasm_bg.wasm
8
+ * 3. wasm-opt -Oz (if available) to shrink the binary
9
+ *
10
+ * The generated bundle is what `<RadProvider mode="local">` loads. Prereqs:
11
+ * rustup target add wasm32-unknown-unknown
12
+ * cargo install wasm-bindgen-cli (version must match the wasm-bindgen crate)
13
+ */
14
+ export {};
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * `rad wasm` — compile the Rust API to WebAssembly for in-browser local dev.
5
+ *
6
+ * Pipeline:
7
+ * 1. cargo build -p rad-wasm --release --target wasm32-unknown-unknown
8
+ * 2. wasm-bindgen --target web → stack/wasm/rad_wasm.js + rad_wasm_bg.wasm
9
+ * 3. wasm-opt -Oz (if available) to shrink the binary
10
+ *
11
+ * The generated bundle is what `<RadProvider mode="local">` loads. Prereqs:
12
+ * rustup target add wasm32-unknown-unknown
13
+ * cargo install wasm-bindgen-cli (version must match the wasm-bindgen crate)
14
+ */
15
+ var __importDefault = (this && this.__importDefault) || function (mod) {
16
+ return (mod && mod.__esModule) ? mod : { "default": mod };
17
+ };
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ const child_process_1 = require("child_process");
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const path_1 = __importDefault(require("path"));
22
+ const repoRoot = path_1.default.resolve(__dirname, "..", "..");
23
+ const rustDir = path_1.default.join(repoRoot, "rust");
24
+ const outDir = path_1.default.join(repoRoot, "stack", "wasm");
25
+ const wasmPath = path_1.default.join(rustDir, "target", "wasm32-unknown-unknown", "release", "rad_wasm.wasm");
26
+ function run(cmd, args, cwd = repoRoot) {
27
+ var _a;
28
+ const result = (0, child_process_1.spawnSync)(cmd, args, { stdio: "inherit", cwd, env: process.env });
29
+ if (result.error) {
30
+ console.error(`\nCould not run \`${cmd}\`. Is it installed and on PATH?`);
31
+ if (cmd === "wasm-bindgen") {
32
+ console.error(" cargo install wasm-bindgen-cli");
33
+ }
34
+ process.exit(1);
35
+ }
36
+ if (result.status !== 0) {
37
+ process.exit((_a = result.status) !== null && _a !== void 0 ? _a : 1);
38
+ }
39
+ }
40
+ function has(cmd) {
41
+ return (0, child_process_1.spawnSync)(cmd, ["--version"], { stdio: "ignore" }).status === 0;
42
+ }
43
+ console.log("→ cargo build -p rad-wasm --release (wasm32-unknown-unknown)");
44
+ run("cargo", [
45
+ "build",
46
+ "-p",
47
+ "rad-wasm",
48
+ "--release",
49
+ "--target",
50
+ "wasm32-unknown-unknown",
51
+ ], rustDir);
52
+ console.log("→ wasm-bindgen → stack/wasm/");
53
+ run("wasm-bindgen", [
54
+ "--target",
55
+ "web",
56
+ "--out-dir",
57
+ outDir,
58
+ "--out-name",
59
+ "rad_wasm",
60
+ wasmPath,
61
+ ]);
62
+ // Mark the emitted bundle as ESM so Node and bundlers treat it correctly
63
+ // without forcing the parent rad-stack package to be a module.
64
+ fs_1.default.writeFileSync(path_1.default.join(outDir, "package.json"), JSON.stringify({ type: "module", sideEffects: false }, null, 2) + "\n");
65
+ if (has("wasm-opt")) {
66
+ console.log("→ wasm-opt -Oz");
67
+ const bg = path_1.default.join(outDir, "rad_wasm_bg.wasm");
68
+ run("wasm-opt", ["-Oz", "-o", bg, bg]);
69
+ }
70
+ else {
71
+ console.log("· wasm-opt not found — skipping size optimisation (optional)");
72
+ }
73
+ const size = fs_1.default.statSync(path_1.default.join(outDir, "rad_wasm_bg.wasm")).size;
74
+ console.log(`✓ wasm engine built: stack/wasm/ (${(size / 1024).toFixed(0)} KB)`);
package/dist/rad.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rad — unified CLI for React API Stack
4
+ *
5
+ * Commands:
6
+ * rad compile [resourcesDir] [outDir] TypeScript resources → schema.rad.json + openapi.json
7
+ * rad check [resourcesDir] Validate the resource graph
8
+ * rad list [resourcesDir] Print resources, fields and relations
9
+ * rad urls [resourcesDir] Print the generated /api/{app}/v1/{model}/ routes
10
+ * rad generate [--schema-only] Generate typed hooks from OpenAPI
11
+ * rad serve [--warehouse dir] Run the Rust API over an Iceberg warehouse
12
+ * rad admin [--warehouse dir] Run the Rust admin (Django-admin-style DB browser)
13
+ * rad wasm Compile the API to WebAssembly (in-browser local dev)
14
+ * rad scan [files...] [--fail-on-pii] Scan CSVs for PII and schema info
15
+ * rad seed [--env dev] [--source gs://] Load CSVs into Iceberg namespace
16
+ */
17
+ export {};
package/dist/rad.js ADDED
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * rad — unified CLI for React API Stack
5
+ *
6
+ * Commands:
7
+ * rad compile [resourcesDir] [outDir] TypeScript resources → schema.rad.json + openapi.json
8
+ * rad check [resourcesDir] Validate the resource graph
9
+ * rad list [resourcesDir] Print resources, fields and relations
10
+ * rad urls [resourcesDir] Print the generated /api/{app}/v1/{model}/ routes
11
+ * rad generate [--schema-only] Generate typed hooks from OpenAPI
12
+ * rad serve [--warehouse dir] Run the Rust API over an Iceberg warehouse
13
+ * rad admin [--warehouse dir] Run the Rust admin (Django-admin-style DB browser)
14
+ * rad wasm Compile the API to WebAssembly (in-browser local dev)
15
+ * rad scan [files...] [--fail-on-pii] Scan CSVs for PII and schema info
16
+ * rad seed [--env dev] [--source gs://] Load CSVs into Iceberg namespace
17
+ */
18
+ var __importDefault = (this && this.__importDefault) || function (mod) {
19
+ return (mod && mod.__esModule) ? mod : { "default": mod };
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ const child_process_1 = require("child_process");
23
+ const path_1 = __importDefault(require("path"));
24
+ const [command, ...rest] = process.argv.slice(2);
25
+ function run(script, args = rest) {
26
+ (0, child_process_1.execSync)(`node ${path_1.default.join(__dirname, script)} ${args.join(" ")}`, {
27
+ stdio: "inherit",
28
+ env: process.env,
29
+ });
30
+ }
31
+ /** Invoke the compiled Rust server binary (built by `cargo build` in rust/). */
32
+ function runRust(subcommand) {
33
+ var _a;
34
+ const repoRoot = path_1.default.resolve(__dirname, "..", "..");
35
+ const binary = process.env.RAD_SERVER_BIN ||
36
+ path_1.default.join(repoRoot, "rust", "target", "release", "rad-server");
37
+ const result = (0, child_process_1.spawnSync)(binary, [subcommand, ...rest], {
38
+ stdio: "inherit",
39
+ env: process.env,
40
+ });
41
+ if (result.error) {
42
+ console.error(`Could not run the Rust server (${binary}). Build it first:\n` +
43
+ ` cd rust && cargo build --release\n`);
44
+ process.exit(1);
45
+ }
46
+ process.exit((_a = result.status) !== null && _a !== void 0 ? _a : 0);
47
+ }
48
+ switch (command) {
49
+ case "compile":
50
+ case "check":
51
+ case "list":
52
+ case "urls":
53
+ // rad-compile dispatches on its own first argument, so pass the command.
54
+ run("rad-compile.js", [command, ...rest]);
55
+ break;
56
+ case "serve":
57
+ runRust("serve");
58
+ break;
59
+ case "admin":
60
+ runRust("admin");
61
+ break;
62
+ case "wasm":
63
+ // Compile the API to WebAssembly for in-browser local dev.
64
+ run("rad-wasm-build.js", rest);
65
+ break;
66
+ case "scan":
67
+ run("scan.js");
68
+ break;
69
+ case "seed":
70
+ run("seed.js");
71
+ break;
72
+ case "generate":
73
+ case "gen":
74
+ // Proxy to existing rastack codegen pipeline
75
+ run("index.js");
76
+ break;
77
+ default:
78
+ console.error(`Unknown command: "${command}"\n\n` +
79
+ `Usage:\n` +
80
+ ` rad compile [resourcesDir] [outDir]\n` +
81
+ ` rad check | list | urls [resourcesDir]\n` +
82
+ ` rad generate [--schema-only]\n` +
83
+ ` rad serve | admin [--warehouse dir]\n` +
84
+ ` rad wasm Compile the API to WebAssembly (browser local dev)\n` +
85
+ ` rad scan [files...] [--fail-on-pii]\n` +
86
+ ` rad seed [--env dev|staging] [--source gs://bucket/ | ./myapp-dev/]\n`);
87
+ process.exit(1);
88
+ }
package/dist/scan.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * rad scan
4
+ *
5
+ * Scans CSV files in myapp-dev/ for PII column patterns and schema issues.
6
+ * Exits non-zero if violations are found and --fail-on-pii is passed.
7
+ *
8
+ * Usage:
9
+ * rad scan [files...] [--fail-on-pii]
10
+ * rad scan myapp-dev/passengers.csv myapp-dev/flights.csv --fail-on-pii
11
+ */
12
+ export {};
package/dist/scan.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * rad scan
5
+ *
6
+ * Scans CSV files in myapp-dev/ for PII column patterns and schema issues.
7
+ * Exits non-zero if violations are found and --fail-on-pii is passed.
8
+ *
9
+ * Usage:
10
+ * rad scan [files...] [--fail-on-pii]
11
+ * rad scan myapp-dev/passengers.csv myapp-dev/flights.csv --fail-on-pii
12
+ */
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ const path_1 = __importDefault(require("path"));
18
+ const csv_schema_1 = require("./csv-schema");
19
+ const args = process.argv.slice(2);
20
+ const failOnPii = args.includes("--fail-on-pii");
21
+ const fileArgs = args.filter((a) => !a.startsWith("--") && a.endsWith(".csv"));
22
+ const repoRoot = process.cwd();
23
+ const devDir = path_1.default.join(repoRoot, "myapp-dev");
24
+ const files = fileArgs.length > 0 ? fileArgs : (0, csv_schema_1.discoverCsvFiles)(devDir);
25
+ if (files.length === 0) {
26
+ console.log("No CSV files found to scan.");
27
+ process.exit(0);
28
+ }
29
+ let totalViolations = 0;
30
+ let hasErrors = false;
31
+ for (const csvPath of files) {
32
+ const rel = path_1.default.relative(repoRoot, csvPath);
33
+ let result;
34
+ try {
35
+ result = (0, csv_schema_1.inferSchema)(csvPath, repoRoot);
36
+ }
37
+ catch (err) {
38
+ console.error(`ERROR ${rel}: ${err.message}`);
39
+ hasErrors = true;
40
+ continue;
41
+ }
42
+ const { schema, piiViolations } = result;
43
+ const colSummary = schema.columns
44
+ .map((c) => {
45
+ const tags = [c.type];
46
+ if (c.primaryKey)
47
+ tags.push("PK");
48
+ if (c.nullable)
49
+ tags.push("nullable");
50
+ if (c.pii)
51
+ tags.push("PII");
52
+ return ` ${c.name.padEnd(24)} ${tags.join(", ")}`;
53
+ })
54
+ .join("\n");
55
+ console.log(`\n${rel} [${schema.rowCount} rows, fingerprint: ${schema.fingerprint}]`);
56
+ console.log(colSummary);
57
+ if (piiViolations.length > 0) {
58
+ totalViolations += piiViolations.length;
59
+ console.log(`\n ⚠ PII violations (${piiViolations.length}):`);
60
+ for (const v of piiViolations) {
61
+ console.log(` ${v.column}: ${v.reason}`);
62
+ }
63
+ }
64
+ }
65
+ console.log("");
66
+ if (hasErrors) {
67
+ console.error("Scan completed with errors.");
68
+ process.exit(1);
69
+ }
70
+ if (totalViolations > 0) {
71
+ console.warn(`Scan found ${totalViolations} PII violation(s) across ${files.length} file(s).`);
72
+ if (failOnPii) {
73
+ console.error("Failing because --fail-on-pii is set. Remove PII data or add access policies in .rad/policies/.");
74
+ process.exit(1);
75
+ }
76
+ }
77
+ else {
78
+ console.log(`Scan passed. ${files.length} file(s) checked, no PII violations.`);
79
+ }
@@ -0,0 +1 @@
1
+ export declare function camelToPastel(str: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.camelToPastel = void 0;
4
+ function camelToPastel(str) {
5
+ return str.charAt(0).toUpperCase() + str.slice(1);
6
+ }
7
+ exports.camelToPastel = camelToPastel;
@@ -0,0 +1 @@
1
+ export declare function capitaliseFirstLetter(str: string): string;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.capitaliseFirstLetter = void 0;
4
+ function capitaliseFirstLetter(str) {
5
+ return str.charAt(0).toUpperCase() + str.slice(1);
6
+ }
7
+ exports.capitaliseFirstLetter = capitaliseFirstLetter;
@@ -0,0 +1,2 @@
1
+ import { OperationObject } from "@ts-stack/openapi-spec";
2
+ export declare function extractResponseBodySchema(methodInformation: OperationObject): [string | undefined, boolean];
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractResponseBodySchema = void 0;
4
+ function extractResponseBodySchema(methodInformation) {
5
+ let responseBodySchema;
6
+ let isList = false;
7
+ if (!methodInformation.responses)
8
+ return [undefined, false];
9
+ Object.keys(methodInformation.responses).forEach((responseKey) => {
10
+ // @ts-ignore
11
+ const responseData = methodInformation.responses[responseKey];
12
+ if (responseData === null || responseData === void 0 ? void 0 : responseData.content) {
13
+ const mediaType = responseData.content["application/json"];
14
+ if (mediaType === null || mediaType === void 0 ? void 0 : mediaType.schema) {
15
+ const refSchema = mediaType.schema.$ref;
16
+ if (refSchema) {
17
+ responseBodySchema = refSchema.replace("#/components/schemas/", "");
18
+ if (responseBodySchema.startsWith("Paginated")) {
19
+ isList = true;
20
+ responseBodySchema = responseBodySchema
21
+ .replace("Paginated", "")
22
+ .slice(0, -4);
23
+ }
24
+ }
25
+ }
26
+ }
27
+ });
28
+ return [responseBodySchema, isList];
29
+ }
30
+ exports.extractResponseBodySchema = extractResponseBodySchema;
@@ -0,0 +1,7 @@
1
+ import { ComponentsObject, PathsObject } from "@ts-stack/openapi-spec";
2
+ interface OpenAPISchema {
3
+ paths: PathsObject;
4
+ components: ComponentsObject;
5
+ }
6
+ export declare function fetchSchema(url: string): Promise<OpenAPISchema>;
7
+ export {};
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.fetchSchema = void 0;
16
+ const axios_1 = __importDefault(require("axios"));
17
+ function fetchSchema(url) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const response = yield axios_1.default.get(url);
20
+ return response.data;
21
+ });
22
+ }
23
+ exports.fetchSchema = fetchSchema;
@@ -0,0 +1,2 @@
1
+ import { PathsObject } from "@ts-stack/openapi-spec";
2
+ export declare function removeNonModelPaths(paths: PathsObject): PathsObject;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeNonModelPaths = void 0;
4
+ function removeNonModelPaths(paths) {
5
+ const filteredPaths = {};
6
+ Object.keys(paths).forEach((key) => {
7
+ const appName = key.split("/")[2];
8
+ const modelName = key.split("/")[4];
9
+ if (appName && modelName) {
10
+ filteredPaths[key] = paths[key];
11
+ }
12
+ });
13
+ return filteredPaths;
14
+ }
15
+ exports.removeNonModelPaths = removeNonModelPaths;
@@ -0,0 +1 @@
1
+ export declare function toCamelCase(str: string): string;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toCamelCase = void 0;
4
+ function toCamelCase(str) {
5
+ const pastel = str
6
+ .split("-")
7
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
8
+ .join("");
9
+ return pastel.charAt(0).toLowerCase() + pastel.slice(1);
10
+ }
11
+ exports.toCamelCase = toCamelCase;
@@ -0,0 +1 @@
1
+ export declare function toPascalCase(str: string): string;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toPascalCase = void 0;
4
+ function toPascalCase(str) {
5
+ return str
6
+ .split("-")
7
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
8
+ .join("");
9
+ }
10
+ exports.toPascalCase = toPascalCase;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ const json_schema_to_typescript_1 = require("json-schema-to-typescript");
15
+ function removeUnknownIndexSignature(code) {
16
+ return code
17
+ .split("\n")
18
+ .filter((line) => !line.includes("[k: string]: unknown;"))
19
+ .join("\n");
20
+ }
21
+ function removeDuplicates(code) {
22
+ const lines = code.split("\n");
23
+ const uniqueExports = new Set();
24
+ let filteredCode = "";
25
+ lines.forEach((line) => {
26
+ if (line.includes("export type ") && !uniqueExports.has(line)) {
27
+ uniqueExports.add(line);
28
+ filteredCode += line + "\n";
29
+ }
30
+ else if (!line.includes("export type ")) {
31
+ filteredCode += line + "\n";
32
+ }
33
+ });
34
+ return filteredCode;
35
+ }
36
+ function main() {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ console.log("Converting Schema");
39
+ const args = process.argv.slice(2);
40
+ const basePath = args[0];
41
+ const schemaFolderPath = (0, path_1.join)(basePath, "api-schema");
42
+ let interfaceFileData = "";
43
+ const schemaFiles = (0, fs_1.readdirSync)(schemaFolderPath);
44
+ let compilePromises = schemaFiles.map((schemaFile) => {
45
+ const schemaFilePath = (0, path_1.join)(schemaFolderPath, schemaFile);
46
+ return (0, json_schema_to_typescript_1.compileFromFile)(schemaFilePath, {
47
+ bannerComment: "",
48
+ style: { useTabs: false, tabWidth: 2 },
49
+ ignoreMinAndMaxItems: true,
50
+ strictIndexSignatures: false,
51
+ }).then((result) => {
52
+ const removedSignature = removeUnknownIndexSignature(result);
53
+ return removedSignature + "\n";
54
+ });
55
+ });
56
+ let results = yield Promise.all(compilePromises);
57
+ interfaceFileData = results.join("\n");
58
+ interfaceFileData = removeDuplicates(interfaceFileData);
59
+ const outputFile = (0, path_1.join)(basePath, "interface.ts");
60
+ (0, fs_1.writeFileSync)(outputFile, interfaceFileData);
61
+ });
62
+ }
63
+ main().catch((error) => console.error(error));
@@ -0,0 +1,14 @@
1
+ import { PathsObject } from "@ts-stack/openapi-spec";
2
+ import { EntitySyncMeta } from "./entity-generation/sync-method";
3
+ /**
4
+ * Pre-pass over the OpenAPI paths: collects, per entity, the sync mode
5
+ * (from rastack's `x-rastack-sync` vendor extension), confirmed operations,
6
+ * the list/detail URLs, the row schema, and the list/detail operation ids
7
+ * (used to wire cache invalidation for non-sync entities).
8
+ */
9
+ export declare function collectEntityMeta(paths: PathsObject): {
10
+ [indexKey: string]: EntitySyncMeta;
11
+ };
12
+ export declare function generateFolders(entitiesPath: string, paths: PathsObject): Promise<void>;
13
+ export declare function generateFiles(entitiesPath: string, paths: PathsObject): Promise<void>;
14
+ export declare function main(url: string, entitiesPath: string): Promise<void>;