New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@toride/codegen

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@toride/codegen - npm Package Compare versions

Comparing version
0.1.0
to
0.2.0
+192
dist/chunk-XMLNKEBL.js
// src/generator.ts
var SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
var ATTRIBUTE_TYPE_MAP = {
string: "string",
number: "number",
boolean: "boolean"
};
function escapeStringLiteral(s) {
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
}
function assertSafeIdentifier(s, context) {
if (!SAFE_IDENTIFIER.test(s)) {
throw new Error(
`Unsafe identifier in ${context}: "${escapeStringLiteral(s)}". Identifiers must match ${SAFE_IDENTIFIER.source}`
);
}
}
function mapAttributeType(attrType, context) {
const mapped = ATTRIBUTE_TYPE_MAP[attrType];
if (!mapped) {
throw new Error(
`Unknown attribute type "${escapeStringLiteral(attrType)}" in ${context}. Supported types: ${Object.keys(ATTRIBUTE_TYPE_MAP).join(", ")}`
);
}
return mapped;
}
function generateAttributeFields(attrs, entityType, entityName) {
const fields = Object.entries(attrs).map(([k, v]) => `${k}: ${mapAttributeType(v, `attribute "${k}" in ${entityType} "${entityName}"`)}`).join("; ");
return `{ ${fields}; }`;
}
function generateTypes(policy) {
const resourceEntries = Object.entries(policy.resources);
const actorEntries = Object.entries(policy.actors);
const resourceNames = resourceEntries.map(([name]) => name);
const actorNames = actorEntries.map(([name]) => name);
const lines = [];
lines.push("// Auto-generated by @toride/codegen \u2014 do not edit");
lines.push("");
lines.push('import type { TorideSchema } from "toride";');
lines.push("");
for (const name of resourceNames) {
assertSafeIdentifier(name, "resource name");
}
for (const [rName, block] of resourceEntries) {
for (const role of block.roles) {
assertSafeIdentifier(role, `role in resource "${rName}"`);
}
for (const perm of block.permissions) {
assertSafeIdentifier(perm, `permission in resource "${rName}"`);
}
if (block.relations) {
for (const [relName, relDef] of Object.entries(block.relations)) {
assertSafeIdentifier(relName, `relation name in resource "${rName}"`);
assertSafeIdentifier(relDef, `relation target in resource "${rName}"`);
}
}
if (block.attributes) {
for (const [attrName, attrType] of Object.entries(block.attributes)) {
assertSafeIdentifier(attrName, `attribute name in resource "${rName}"`);
mapAttributeType(attrType, `attribute "${attrName}" in resource "${rName}"`);
}
}
}
for (const [actorName, actorDecl] of actorEntries) {
assertSafeIdentifier(actorName, "actor type name");
for (const [attrName, attrType] of Object.entries(actorDecl.attributes)) {
assertSafeIdentifier(attrName, `attribute name in actor "${actorName}"`);
mapAttributeType(attrType, `attribute "${attrName}" in actor "${actorName}"`);
}
}
const allActions = /* @__PURE__ */ new Set();
for (const [, block] of resourceEntries) {
for (const perm of block.permissions) {
allActions.add(perm);
}
}
lines.push(`/** All action strings declared across all resources */`);
if (allActions.size === 0) {
lines.push("export type Actions = never;");
} else {
const actionUnion = [...allActions].map((a) => `"${a}"`).join(" | ");
lines.push(`export type Actions = ${actionUnion};`);
}
lines.push("");
lines.push(`/** All resource type names */`);
if (resourceNames.length === 0) {
lines.push("export type Resources = never;");
} else {
const resourceUnion = resourceNames.map((r) => `"${r}"`).join(" | ");
lines.push(`export type Resources = ${resourceUnion};`);
}
lines.push("");
lines.push(`/** All actor type names */`);
if (actorNames.length === 0) {
lines.push("export type ActorTypes = never;");
} else {
const actorUnion = actorNames.map((a) => `"${a}"`).join(" | ");
lines.push(`export type ActorTypes = ${actorUnion};`);
}
lines.push("");
lines.push(`/** Per-resource role types */`);
lines.push(`export interface RoleMap {`);
for (const [name, block] of resourceEntries) {
if (block.roles.length > 0) {
const roleUnion = block.roles.map((r) => `"${r}"`).join(" | ");
lines.push(` ${name}: ${roleUnion};`);
} else {
lines.push(` ${name}: never;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-resource permission types */`);
lines.push(`export interface PermissionMap {`);
for (const [name, block] of resourceEntries) {
if (block.permissions.length > 0) {
const permUnion = block.permissions.map((p) => `"${p}"`).join(" | ");
lines.push(` ${name}: ${permUnion};`);
} else {
lines.push(` ${name}: never;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-resource attribute types */`);
lines.push(`export interface ResourceAttributeMap {`);
for (const [name, block] of resourceEntries) {
if (block.attributes && Object.keys(block.attributes).length > 0) {
lines.push(` ${name}: ${generateAttributeFields(block.attributes, "resource", name)};`);
} else {
lines.push(` ${name}: Record<string, unknown>;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-actor attribute types */`);
lines.push(`export interface ActorAttributeMap {`);
for (const [name, actorDecl] of actorEntries) {
const attrKeys = Object.keys(actorDecl.attributes);
if (attrKeys.length > 0) {
lines.push(` ${name}: ${generateAttributeFields(actorDecl.attributes, "actor", name)};`);
} else {
lines.push(` ${name}: Record<string, unknown>;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Relation map \u2014 resource type -> relation name -> target resource type */`);
lines.push(`export interface RelationMap {`);
for (const [name, block] of resourceEntries) {
const relations = block.relations ?? {};
const relEntries = Object.entries(relations);
if (relEntries.length === 0) {
lines.push(` ${name}: Record<string, never>;`);
} else {
lines.push(` ${name}: {`);
for (const [relName, relDef] of relEntries) {
lines.push(` ${relName}: "${relDef}";`);
}
lines.push(` };`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-type resolver map \u2014 typed return values match resource attributes */`);
lines.push(`export type ResolverMap = {`);
lines.push(` [R in Resources]?: (`);
lines.push(` ref: { type: R; id: string; attributes?: ResourceAttributeMap[R] },`);
lines.push(` ) => Promise<ResourceAttributeMap[R]>;`);
lines.push(`};`);
lines.push("");
lines.push(`/**`);
lines.push(` * Unified schema interface \u2014 pass this as Toride<GeneratedSchema>.`);
lines.push(` * Aggregates all type maps into the TorideSchema shape.`);
lines.push(` */`);
lines.push(`export interface GeneratedSchema extends TorideSchema {`);
lines.push(` resources: Resources;`);
lines.push(` actions: Actions;`);
lines.push(` actorTypes: ActorTypes;`);
lines.push(` permissionMap: PermissionMap;`);
lines.push(` roleMap: RoleMap;`);
lines.push(` resourceAttributeMap: ResourceAttributeMap;`);
lines.push(` actorAttributeMap: ActorAttributeMap;`);
lines.push(` relationMap: RelationMap;`);
lines.push(`}`);
lines.push("");
return lines.join("\n");
}
export {
generateTypes
};
+1
-1
#!/usr/bin/env node
import {
generateTypes
} from "./chunk-ON3XL4K7.js";
} from "./chunk-XMLNKEBL.js";

@@ -6,0 +6,0 @@ // src/cli.ts

import {
generateTypes
} from "./chunk-ON3XL4K7.js";
} from "./chunk-XMLNKEBL.js";

@@ -5,0 +5,0 @@ // src/index.ts

{
"name": "@toride/codegen",
"version": "0.1.0",
"version": "0.2.0",
"description": "Code generation tools for Toride authorization engine",

@@ -26,3 +26,3 @@ "type": "module",

"dependencies": {
"toride": "0.1.0"
"toride": "0.2.0"
},

@@ -29,0 +29,0 @@ "publishConfig": {

// src/generator.ts
var SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
function escapeStringLiteral(s) {
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
}
function assertSafeIdentifier(s, context) {
if (!SAFE_IDENTIFIER.test(s)) {
throw new Error(
`Unsafe identifier in ${context}: "${escapeStringLiteral(s)}". Identifiers must match ${SAFE_IDENTIFIER.source}`
);
}
}
function generateTypes(policy) {
const resourceNames = Object.keys(policy.resources);
const lines = [];
lines.push("// Auto-generated by @toride/codegen \u2014 do not edit");
lines.push("");
for (const name of resourceNames) {
assertSafeIdentifier(name, "resource name");
}
for (const [rName, block] of Object.entries(policy.resources)) {
for (const role of block.roles) {
assertSafeIdentifier(role, `role in resource "${rName}"`);
}
for (const perm of block.permissions) {
assertSafeIdentifier(perm, `permission in resource "${rName}"`);
}
if (block.relations) {
for (const [relName, relDef] of Object.entries(block.relations)) {
assertSafeIdentifier(relName, `relation name in resource "${rName}"`);
assertSafeIdentifier(relDef, `relation target in resource "${rName}"`);
}
}
}
const allActions = /* @__PURE__ */ new Set();
for (const block of Object.values(policy.resources)) {
for (const perm of block.permissions) {
allActions.add(perm);
}
}
lines.push(`/** All action strings declared across all resources */`);
if (allActions.size === 0) {
lines.push("export type Actions = never;");
} else {
const actionUnion = [...allActions].map((a) => `"${a}"`).join(" | ");
lines.push(`export type Actions = ${actionUnion};`);
}
lines.push("");
lines.push(`/** All resource type names */`);
if (resourceNames.length === 0) {
lines.push("export type Resources = never;");
} else {
const resourceUnion = resourceNames.map((r) => `"${r}"`).join(" | ");
lines.push(`export type Resources = ${resourceUnion};`);
}
lines.push("");
lines.push(`/** Per-resource role types */`);
lines.push(`export interface RoleMap {`);
for (const [name, block] of Object.entries(policy.resources)) {
if (block.roles.length > 0) {
const roleUnion = block.roles.map((r) => `"${r}"`).join(" | ");
lines.push(` ${name}: ${roleUnion};`);
} else {
lines.push(` ${name}: never;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-resource permission types */`);
lines.push(`export interface PermissionMap {`);
for (const [name, block] of Object.entries(policy.resources)) {
if (block.permissions.length > 0) {
const permUnion = block.permissions.map((p) => `"${p}"`).join(" | ");
lines.push(` ${name}: ${permUnion};`);
} else {
lines.push(` ${name}: never;`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Relation map \u2014 resource type -> relation name -> target resource type */`);
lines.push(`export interface RelationMap {`);
for (const [name, block] of Object.entries(policy.resources)) {
const relations = block.relations ?? {};
const relEntries = Object.entries(relations);
if (relEntries.length === 0) {
lines.push(` ${name}: Record<string, never>;`);
} else {
lines.push(` ${name}: {`);
for (const [relName, relDef] of relEntries) {
lines.push(` ${relName}: "${relDef}";`);
}
lines.push(` };`);
}
}
lines.push(`}`);
lines.push("");
lines.push(`/** Per-type resolver map \u2014 TypeScript ensures all resource types have resolvers */`);
lines.push(`export type ResolverMap = {`);
lines.push(` [R in Resources]?: (`);
lines.push(` ref: { type: R; id: string; attributes?: Record<string, unknown> },`);
lines.push(` ) => Promise<Record<string, unknown>>;`);
lines.push(`};`);
lines.push("");
return lines.join("\n");
}
export {
generateTypes
};