diff --git a/browser/cli/src/commands/init.ts b/browser/cli/src/commands/init.ts index 5d85acf71..b28b962c7 100644 --- a/browser/cli/src/commands/init.ts +++ b/browser/cli/src/commands/init.ts @@ -12,9 +12,9 @@ const TEMPLATE_CONFIG_FILE = { export const initCommand = async (args: string[]) => { const forced = args.includes('--force') || args.includes('-f'); const filePath = path.join(process.cwd(), 'atomic.config.json'); - const stat = fs.statSync(filePath); + const stat = fs.statSync(filePath, { throwIfNoEntry: false }); - if (stat.isFile() && !forced) { + if (stat?.isFile() && !forced) { return console.error( chalk.red( `ERROR: File already exists. If you meant to override the existing file, use the command with the ${chalk.cyan( diff --git a/browser/cli/src/config.ts b/browser/cli/src/config.ts index 111904059..9ca165b9a 100644 --- a/browser/cli/src/config.ts +++ b/browser/cli/src/config.ts @@ -11,6 +11,10 @@ export interface AtomicConfig { * The default should be sufficient in most but if you have given the module an alias you should change this value */ moduleAlias?: string; + /** + * [OPTIONAL] By default we generate class types for ease of use (e.g: export type Property = typeof core.classes.property;). But these names can clash with other interfaces or classes in your project. When 'useNameSpaces' is set to true the types will be wrapped in a namespace. + */ + useNamespaces?: boolean; /** * [OPTIONAL] The secret of the agent that is used to access your atomic data server. This can also be provided as a command line argument if you don't want to store it in the config file. * If left empty the public agent is used. diff --git a/browser/cli/src/generateClassExports.ts b/browser/cli/src/generateClassExports.ts index 604955f95..00e07216d 100644 --- a/browser/cli/src/generateClassExports.ts +++ b/browser/cli/src/generateClassExports.ts @@ -1,15 +1,28 @@ import { Resource, urls } from '@tomic/lib'; +import { atomicConfig } from './config.js'; import { ReverseMapping } from './generateBaseObject.js'; import { store } from './store.js'; import { camelCaseify } from './utils.js'; +enum Inserts { + NamespaceName = '{{1}}', + NamespaceBody = '{{2}}', +} + +const NAMESPACE_TEMPLATE = ` + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace ${Inserts.NamespaceName} { + ${Inserts.NamespaceBody} + } +`; + export const generateClassExports = ( ontology: Resource, reverseMapping: ReverseMapping, ): string => { const classes = ontology.getArray(urls.properties.classes) as string[]; - return classes + const body = classes .map(subject => { const res = store.getResourceLoading(subject); const objectPath = reverseMapping[subject]; @@ -17,6 +30,15 @@ export const generateClassExports = ( return createExportLine(res.title, objectPath); }) .join('\n'); + + if (atomicConfig.useNamespaces) { + return NAMESPACE_TEMPLATE.replace( + Inserts.NamespaceName, + capitalize(ontology.title), + ).replace(Inserts.NamespaceBody, body); + } else { + return body; + } }; const createExportLine = (title: string, objectPath: string) => diff --git a/browser/lib/atomic.config.json b/browser/lib/atomic.config.json new file mode 100644 index 000000000..fe2d58954 --- /dev/null +++ b/browser/lib/atomic.config.json @@ -0,0 +1,12 @@ +{ + "outputFolder": "./src/ontologies", + "moduleAlias": "../index.js", + "useNamespaces": true, + "ontologies": [ + "https://atomicdata.dev/ontology/core", + "https://atomicdata.dev/ontology/commit", + "https://atomicdata.dev/ontology/collection", + "https://atomicdata.dev/ontology/data-browser", + "https://atomicdata.dev/ontology/server" + ] +} diff --git a/browser/lib/package.json b/browser/lib/package.json index 2be95f095..447ba6109 100644 --- a/browser/lib/package.json +++ b/browser/lib/package.json @@ -13,7 +13,8 @@ "@types/fast-json-stable-stringify": "^2.1.0", "chai": "^4.3.4", "typescript": "^4.8", - "whatwg-fetch": "^3.6.2" + "whatwg-fetch": "^3.6.2", + "@tomic/cli": "^0.35.2" }, "files": [ "dist" @@ -34,7 +35,8 @@ "start": "pnpm watch", "test": "NODE_OPTIONS='--experimental-vm-modules' ../node_modules/jest/bin/jest.js", "tsc": "tsc --build", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "generate-ontologies": "ad-generate ontologies" }, "source": "src/index.ts", "type": "module", diff --git a/browser/lib/src/index.ts b/browser/lib/src/index.ts index f0071a603..e7209ccf2 100644 --- a/browser/lib/src/index.ts +++ b/browser/lib/src/index.ts @@ -29,6 +29,15 @@ * @module */ +import { initOntologies } from './ontologies/index.js'; + +initOntologies(); + +export * from './ontologies/core.js'; +export * from './ontologies/collections.js'; +export * from './ontologies/commits.js'; +export * from './ontologies/dataBrowser.js'; +export * from './ontologies/server.js'; export * from './agent.js'; export * from './authentication.js'; export * from './class.js'; diff --git a/browser/lib/src/ontologies/collections.ts b/browser/lib/src/ontologies/collections.ts new file mode 100644 index 000000000..5da60fc95 --- /dev/null +++ b/browser/lib/src/ontologies/collections.ts @@ -0,0 +1,66 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { BaseProps } from '../index.js' + +export const collections = { + classes: { + collection: 'https://atomicdata.dev/classes/Collection', + }, + properties: { + members: 'https://atomicdata.dev/properties/collection/members', + currentPage: 'https://atomicdata.dev/properties/collection/currentPage', + pageSize: 'https://atomicdata.dev/properties/collection/pageSize', + property: 'https://atomicdata.dev/properties/collection/property', + totalMembers: 'https://atomicdata.dev/properties/collection/totalMembers', + totalPages: 'https://atomicdata.dev/properties/collection/totalPages', + value: 'https://atomicdata.dev/properties/collection/value', + sortBy: 'https://atomicdata.dev/properties/collection/sortBy', + sortDesc: 'https://atomicdata.dev/properties/collection/sortDesc', + includeExternal: 'https://atomicdata.dev/properties/collection/includeExternal', + }, + } as const + + + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Collections { + export type Collection = typeof collections.classes.collection; + } + + +declare module '../index.js' { + interface Classes { + [collections.classes.collection]: { + requires: BaseProps; + recommends: 'https://atomicdata.dev/properties/name' | 'https://atomicdata.dev/properties/description' | typeof collections.properties.currentPage | typeof collections.properties.members | typeof collections.properties.pageSize | typeof collections.properties.property | typeof collections.properties.sortBy | typeof collections.properties.sortDesc | typeof collections.properties.totalMembers | typeof collections.properties.totalPages | typeof collections.properties.value | typeof collections.properties.includeExternal | 'https://atomicdata.dev/properties/incomplete'; + }; + } + + interface PropTypeMapping { + [collections.properties.members]: string[] +[collections.properties.currentPage]: number +[collections.properties.pageSize]: number +[collections.properties.property]: string +[collections.properties.totalMembers]: number +[collections.properties.totalPages]: number +[collections.properties.value]: string +[collections.properties.sortBy]: string +[collections.properties.sortDesc]: boolean +[collections.properties.includeExternal]: boolean + } + + interface PropSubjectToNameMapping { + [collections.properties.members]: 'members', +[collections.properties.currentPage]: 'currentPage', +[collections.properties.pageSize]: 'pageSize', +[collections.properties.property]: 'property', +[collections.properties.totalMembers]: 'totalMembers', +[collections.properties.totalPages]: 'totalPages', +[collections.properties.value]: 'value', +[collections.properties.sortBy]: 'sortBy', +[collections.properties.sortDesc]: 'sortDesc', +[collections.properties.includeExternal]: 'includeExternal', + } +} diff --git a/browser/lib/src/ontologies/commits.ts b/browser/lib/src/ontologies/commits.ts new file mode 100644 index 000000000..9d2e1a379 --- /dev/null +++ b/browser/lib/src/ontologies/commits.ts @@ -0,0 +1,66 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { BaseProps } from '../index.js' + +export const commits = { + classes: { + commit: 'https://atomicdata.dev/classes/Commit', + }, + properties: { + subject: 'https://atomicdata.dev/properties/subject', + createdAt: 'https://atomicdata.dev/properties/createdAt', + lastCommit: 'https://atomicdata.dev/properties/lastCommit', + previousCommit: 'https://atomicdata.dev/properties/previousCommit', + signer: 'https://atomicdata.dev/properties/signer', + set: 'https://atomicdata.dev/properties/set', + push: 'https://atomicdata.dev/properties/push', + remove: 'https://atomicdata.dev/properties/remove', + destroy: 'https://atomicdata.dev/properties/destroy', + signature: 'https://atomicdata.dev/properties/signature', + }, + } as const + + + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Commits { + export type Commit = typeof commits.classes.commit; + } + + +declare module '../index.js' { + interface Classes { + [commits.classes.commit]: { + requires: BaseProps | typeof commits.properties.createdAt | typeof commits.properties.signature | typeof commits.properties.signer | typeof commits.properties.subject; + recommends: typeof commits.properties.destroy | typeof commits.properties.remove | typeof commits.properties.set; + }; + } + + interface PropTypeMapping { + [commits.properties.subject]: string +[commits.properties.createdAt]: string +[commits.properties.lastCommit]: string +[commits.properties.previousCommit]: string +[commits.properties.signer]: string +[commits.properties.set]: string +[commits.properties.push]: string +[commits.properties.remove]: string[] +[commits.properties.destroy]: boolean +[commits.properties.signature]: string + } + + interface PropSubjectToNameMapping { + [commits.properties.subject]: 'subject', +[commits.properties.createdAt]: 'createdAt', +[commits.properties.lastCommit]: 'lastCommit', +[commits.properties.previousCommit]: 'previousCommit', +[commits.properties.signer]: 'signer', +[commits.properties.set]: 'set', +[commits.properties.push]: 'push', +[commits.properties.remove]: 'remove', +[commits.properties.destroy]: 'destroy', +[commits.properties.signature]: 'signature', + } +} diff --git a/browser/lib/src/ontologies/core.ts b/browser/lib/src/ontologies/core.ts new file mode 100644 index 000000000..059f0b4cd --- /dev/null +++ b/browser/lib/src/ontologies/core.ts @@ -0,0 +1,117 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { BaseProps } from '../index.js' + +export const core = { + classes: { + class: 'https://atomicdata.dev/classes/Class', + property: 'https://atomicdata.dev/classes/Property', + agent: 'https://atomicdata.dev/classes/Agent', + datatype: 'https://atomicdata.dev/classes/Datatype', + ontology: 'https://atomicdata.dev/class/ontology', + }, + properties: { + allowsOnly: 'https://atomicdata.dev/properties/allowsOnly', + classtype: 'https://atomicdata.dev/properties/classtype', + datatype: 'https://atomicdata.dev/properties/datatype', + description: 'https://atomicdata.dev/properties/description', + incomplete: 'https://atomicdata.dev/properties/incomplete', + isA: 'https://atomicdata.dev/properties/isA', + isDynamic: 'https://atomicdata.dev/properties/isDynamic', + name: 'https://atomicdata.dev/properties/name', + parent: 'https://atomicdata.dev/properties/parent', + read: 'https://atomicdata.dev/properties/read', + recommends: 'https://atomicdata.dev/properties/recommends', + requires: 'https://atomicdata.dev/properties/requires', + shortname: 'https://atomicdata.dev/properties/shortname', + write: 'https://atomicdata.dev/properties/write', + publicKey: 'https://atomicdata.dev/properties/publicKey', + instances: 'https://atomicdata.dev/properties/instances', + properties: 'https://atomicdata.dev/properties/properties', + classes: 'https://atomicdata.dev/properties/classes', + isLocked: 'https://atomicdata.dev/properties/isLocked', + }, + } as const + + + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Core { + export type Class = typeof core.classes.class; +export type Property = typeof core.classes.property; +export type Agent = typeof core.classes.agent; +export type Datatype = typeof core.classes.datatype; +export type Ontology = typeof core.classes.ontology; + } + + +declare module '../index.js' { + interface Classes { + [core.classes.class]: { + requires: BaseProps | typeof core.properties.shortname | typeof core.properties.description; + recommends: typeof core.properties.recommends | typeof core.properties.requires; + }; +[core.classes.property]: { + requires: BaseProps | typeof core.properties.shortname | typeof core.properties.datatype | typeof core.properties.description; + recommends: typeof core.properties.classtype | typeof core.properties.isDynamic | typeof core.properties.isLocked | typeof core.properties.allowsOnly; + }; +[core.classes.agent]: { + requires: BaseProps | typeof core.properties.publicKey; + recommends: typeof core.properties.name | typeof core.properties.description | 'https://atomicdata.dev/properties/drives'; + }; +[core.classes.datatype]: { + requires: BaseProps | typeof core.properties.shortname | typeof core.properties.description; + recommends: never; + }; +[core.classes.ontology]: { + requires: BaseProps | typeof core.properties.description | typeof core.properties.shortname; + recommends: typeof core.properties.classes | typeof core.properties.properties | typeof core.properties.instances; + }; + } + + interface PropTypeMapping { + [core.properties.allowsOnly]: string[] +[core.properties.classtype]: string +[core.properties.datatype]: string +[core.properties.description]: string +[core.properties.incomplete]: boolean +[core.properties.isA]: string[] +[core.properties.isDynamic]: boolean +[core.properties.name]: string +[core.properties.parent]: string +[core.properties.read]: string[] +[core.properties.recommends]: string[] +[core.properties.requires]: string[] +[core.properties.shortname]: string +[core.properties.write]: string[] +[core.properties.publicKey]: string +[core.properties.instances]: string[] +[core.properties.properties]: string[] +[core.properties.classes]: string[] +[core.properties.isLocked]: boolean + } + + interface PropSubjectToNameMapping { + [core.properties.allowsOnly]: 'allowsOnly', +[core.properties.classtype]: 'classtype', +[core.properties.datatype]: 'datatype', +[core.properties.description]: 'description', +[core.properties.incomplete]: 'incomplete', +[core.properties.isA]: 'isA', +[core.properties.isDynamic]: 'isDynamic', +[core.properties.name]: 'name', +[core.properties.parent]: 'parent', +[core.properties.read]: 'read', +[core.properties.recommends]: 'recommends', +[core.properties.requires]: 'requires', +[core.properties.shortname]: 'shortname', +[core.properties.write]: 'write', +[core.properties.publicKey]: 'publicKey', +[core.properties.instances]: 'instances', +[core.properties.properties]: 'properties', +[core.properties.classes]: 'classes', +[core.properties.isLocked]: 'isLocked', + } +} diff --git a/browser/lib/src/ontologies/dataBrowser.ts b/browser/lib/src/ontologies/dataBrowser.ts new file mode 100644 index 000000000..c57c35f09 --- /dev/null +++ b/browser/lib/src/ontologies/dataBrowser.ts @@ -0,0 +1,204 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { BaseProps } from '../index.js' + +export const dataBrowser = { + classes: { + chatroom: 'https://atomicdata.dev/classes/ChatRoom', + document: 'https://atomicdata.dev/classes/Document', + bookmark: 'https://atomicdata.dev/class/Bookmark', + paragraph: 'https://atomicdata.dev/classes/elements/Paragraph', + message: 'https://atomicdata.dev/classes/Message', + importer: 'https://atomicdata.dev/classes/Importer', + folder: 'https://atomicdata.dev/classes/Folder', + article: 'https://atomicdata.dev/classes/Article', + displayStyle: 'https://atomicdata.dev/class/DisplayStyle', + dateFormat: 'https://atomicdata.dev/classes/DateFormat', + numberFormat: 'https://atomicdata.dev/classes/NumberFormat', + rangeProperty: 'https://atomicdata.dev/classes/RangeProperty', + floatRangeProperty: 'https://atomicdata.dev/classes/FloatRangeProperty', + formattedNumber: 'https://atomicdata.dev/classes/FormattedNumber', + selectProperty: 'https://atomicdata.dev/classes/SelectProperty', + formattedDate: 'https://atomicdata.dev/classes/FormattedDate', + table: 'https://atomicdata.dev/classes/Table', + tag: 'https://atomicdata.dev/classes/Tag', + }, + properties: { + subResources: 'https://atomicdata.dev/properties/subresources', + displayStyle: 'https://atomicdata.dev/property/display-style', + publishedAt: 'https://atomicdata.dev/properties/published-at', + elements: 'https://atomicdata.dev/properties/documents/elements', + messages: 'https://atomicdata.dev/properties/messages', + nextPage: 'https://atomicdata.dev/properties/nextPage', + replyTo: 'https://atomicdata.dev/properties/replyTo', + url: 'https://atomicdata.dev/property/url', + preview: 'https://atomicdata.dev/property/preview', + imageUrl: 'https://atomicdata.dev/properties/imageUrl', + max: 'https://atomicdata.dev/properties/max', + min: 'https://atomicdata.dev/properties/min', + maxFloat: 'https://atomicdata.dev/properties/maxFloat', + minFloat: 'https://atomicdata.dev/properties/minFloat', + numberFormatting: 'https://atomicdata.dev/properties/numberFormatting', + decimalPlaces: 'https://atomicdata.dev/properties/decimalPlaces', + dateFormat: 'https://atomicdata.dev/properties/dateFormat', + tableColumnWidths: 'https://atomicdata.dev/properties/tableColumnWidths', + customNodePositioning: 'https://atomicdata.dev/properties/custom-node-positioning', + color: 'https://atomicdata.dev/properties/color', + emoji: 'https://atomicdata.dev/properties/emoji', + tags: 'https://atomicdata.dev/properties/tags', + }, + } as const + + + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace DataBrowser { + export type Chatroom = typeof dataBrowser.classes.chatroom; +export type Document = typeof dataBrowser.classes.document; +export type Bookmark = typeof dataBrowser.classes.bookmark; +export type Paragraph = typeof dataBrowser.classes.paragraph; +export type Message = typeof dataBrowser.classes.message; +export type Importer = typeof dataBrowser.classes.importer; +export type Folder = typeof dataBrowser.classes.folder; +export type Article = typeof dataBrowser.classes.article; +export type DisplayStyle = typeof dataBrowser.classes.displayStyle; +export type DateFormat = typeof dataBrowser.classes.dateFormat; +export type NumberFormat = typeof dataBrowser.classes.numberFormat; +export type RangeProperty = typeof dataBrowser.classes.rangeProperty; +export type FloatRangeProperty = typeof dataBrowser.classes.floatRangeProperty; +export type FormattedNumber = typeof dataBrowser.classes.formattedNumber; +export type SelectProperty = typeof dataBrowser.classes.selectProperty; +export type FormattedDate = typeof dataBrowser.classes.formattedDate; +export type Table = typeof dataBrowser.classes.table; +export type Tag = typeof dataBrowser.classes.tag; + } + + +declare module '../index.js' { + interface Classes { + [dataBrowser.classes.chatroom]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name'; + recommends: typeof dataBrowser.properties.messages; + }; +[dataBrowser.classes.document]: { + requires: BaseProps; + recommends: typeof dataBrowser.properties.elements | 'https://atomicdata.dev/properties/name'; + }; +[dataBrowser.classes.bookmark]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name' | typeof dataBrowser.properties.url; + recommends: typeof dataBrowser.properties.preview | 'https://atomicdata.dev/properties/description' | typeof dataBrowser.properties.imageUrl; + }; +[dataBrowser.classes.paragraph]: { + requires: BaseProps | 'https://atomicdata.dev/properties/description' | 'https://atomicdata.dev/properties/parent'; + recommends: never; + }; +[dataBrowser.classes.message]: { + requires: BaseProps | 'https://atomicdata.dev/properties/description' | 'https://atomicdata.dev/properties/parent'; + recommends: never; + }; +[dataBrowser.classes.importer]: { + requires: BaseProps; + recommends: never; + }; +[dataBrowser.classes.folder]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name' | typeof dataBrowser.properties.displayStyle; + recommends: typeof dataBrowser.properties.subResources; + }; +[dataBrowser.classes.article]: { + requires: BaseProps | 'https://atomicdata.dev/properties/description' | 'https://atomicdata.dev/properties/name'; + recommends: typeof dataBrowser.properties.tags | typeof dataBrowser.properties.publishedAt; + }; +[dataBrowser.classes.displayStyle]: { + requires: BaseProps | 'https://atomicdata.dev/properties/name'; + recommends: never; + }; +[dataBrowser.classes.dateFormat]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: never; + }; +[dataBrowser.classes.numberFormat]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: typeof dataBrowser.properties.decimalPlaces; + }; +[dataBrowser.classes.rangeProperty]: { + requires: BaseProps; + recommends: typeof dataBrowser.properties.min | typeof dataBrowser.properties.max; + }; +[dataBrowser.classes.floatRangeProperty]: { + requires: BaseProps; + recommends: typeof dataBrowser.properties.minFloat | typeof dataBrowser.properties.maxFloat; + }; +[dataBrowser.classes.formattedNumber]: { + requires: BaseProps | typeof dataBrowser.properties.numberFormatting; + recommends: typeof dataBrowser.properties.decimalPlaces; + }; +[dataBrowser.classes.selectProperty]: { + requires: BaseProps | 'https://atomicdata.dev/properties/allowsOnly'; + recommends: typeof dataBrowser.properties.max; + }; +[dataBrowser.classes.formattedDate]: { + requires: BaseProps | typeof dataBrowser.properties.dateFormat; + recommends: never; + }; +[dataBrowser.classes.table]: { + requires: BaseProps | 'https://atomicdata.dev/properties/classtype' | 'https://atomicdata.dev/properties/name'; + recommends: never; + }; +[dataBrowser.classes.tag]: { + requires: BaseProps | 'https://atomicdata.dev/properties/shortname'; + recommends: typeof dataBrowser.properties.color | typeof dataBrowser.properties.emoji; + }; + } + + interface PropTypeMapping { + [dataBrowser.properties.subResources]: string[] +[dataBrowser.properties.displayStyle]: string +[dataBrowser.properties.publishedAt]: string +[dataBrowser.properties.elements]: string[] +[dataBrowser.properties.messages]: string[] +[dataBrowser.properties.nextPage]: string +[dataBrowser.properties.replyTo]: string +[dataBrowser.properties.url]: string +[dataBrowser.properties.preview]: string +[dataBrowser.properties.imageUrl]: string +[dataBrowser.properties.max]: number +[dataBrowser.properties.min]: number +[dataBrowser.properties.maxFloat]: number +[dataBrowser.properties.minFloat]: number +[dataBrowser.properties.numberFormatting]: string +[dataBrowser.properties.decimalPlaces]: number +[dataBrowser.properties.dateFormat]: string +[dataBrowser.properties.tableColumnWidths]: string +[dataBrowser.properties.customNodePositioning]: string +[dataBrowser.properties.color]: string +[dataBrowser.properties.emoji]: string +[dataBrowser.properties.tags]: string[] + } + + interface PropSubjectToNameMapping { + [dataBrowser.properties.subResources]: 'subResources', +[dataBrowser.properties.displayStyle]: 'displayStyle', +[dataBrowser.properties.publishedAt]: 'publishedAt', +[dataBrowser.properties.elements]: 'elements', +[dataBrowser.properties.messages]: 'messages', +[dataBrowser.properties.nextPage]: 'nextPage', +[dataBrowser.properties.replyTo]: 'replyTo', +[dataBrowser.properties.url]: 'url', +[dataBrowser.properties.preview]: 'preview', +[dataBrowser.properties.imageUrl]: 'imageUrl', +[dataBrowser.properties.max]: 'max', +[dataBrowser.properties.min]: 'min', +[dataBrowser.properties.maxFloat]: 'maxFloat', +[dataBrowser.properties.minFloat]: 'minFloat', +[dataBrowser.properties.numberFormatting]: 'numberFormatting', +[dataBrowser.properties.decimalPlaces]: 'decimalPlaces', +[dataBrowser.properties.dateFormat]: 'dateFormat', +[dataBrowser.properties.tableColumnWidths]: 'tableColumnWidths', +[dataBrowser.properties.customNodePositioning]: 'customNodePositioning', +[dataBrowser.properties.color]: 'color', +[dataBrowser.properties.emoji]: 'emoji', +[dataBrowser.properties.tags]: 'tags', + } +} diff --git a/browser/lib/src/ontologies/index.ts b/browser/lib/src/ontologies/index.ts new file mode 100644 index 000000000..1911f3f89 --- /dev/null +++ b/browser/lib/src/ontologies/index.ts @@ -0,0 +1,16 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { registerOntologies } from '../index.js'; + +import { core } from './core.js'; +import { commits } from './commits.js'; +import { collections } from './collections.js'; +import { dataBrowser } from './dataBrowser.js'; +import { server } from './server.js'; + +export function initOntologies(): void { + registerOntologies(core, commits, collections, dataBrowser, server); +} diff --git a/browser/lib/src/ontologies/server.ts b/browser/lib/src/ontologies/server.ts new file mode 100644 index 000000000..cd6d2bbd3 --- /dev/null +++ b/browser/lib/src/ontologies/server.ts @@ -0,0 +1,129 @@ + +/* ----------------------------------- +* GENERATED WITH ATOMIC-GENERATE +* -------------------------------- */ + +import { BaseProps } from '../index.js' + +export const server = { + classes: { + error: 'https://atomicdata.dev/classes/Error', + endpoint: 'https://atomicdata.dev/classes/Endpoint', + drive: 'https://atomicdata.dev/classes/Drive', + redirect: 'https://atomicdata.dev/classes/Redirect', + file: 'https://atomicdata.dev/classes/File', + invite: 'https://atomicdata.dev/classes/Invite', + }, + properties: { + drives: 'https://atomicdata.dev/properties/drives', + results: 'https://atomicdata.dev/properties/endpoint/results', + property: 'https://atomicdata.dev/properties/search/property', + redirectAgent: 'https://atomicdata.dev/properties/invite/redirectAgent', + agent: 'https://atomicdata.dev/properties/invite/agent', + publicKey: 'https://atomicdata.dev/properties/invite/publicKey', + target: 'https://atomicdata.dev/properties/invite/target', + usagesLeft: 'https://atomicdata.dev/properties/invite/usagesLeft', + users: 'https://atomicdata.dev/properties/invite/users', + write: 'https://atomicdata.dev/properties/invite/write', + filename: 'https://atomicdata.dev/properties/filename', + filesize: 'https://atomicdata.dev/properties/filesize', + downloadUrl: 'https://atomicdata.dev/properties/downloadURL', + mimetype: 'https://atomicdata.dev/properties/mimetype', + attachments: 'https://atomicdata.dev/properties/attachments', + createdBy: 'https://atomicdata.dev/properties/createdBy', + checksum: 'https://atomicdata.dev/properties/checksum', + internalId: 'https://atomicdata.dev/properties/internalId', + children: 'https://atomicdata.dev/properties/children', + parameters: 'https://atomicdata.dev/properties/endpoint/parameters', + destination: 'https://atomicdata.dev/properties/destination', + }, + } as const + + + // eslint-disable-next-line @typescript-eslint/no-namespace + export namespace Server { + export type Error = typeof server.classes.error; +export type Endpoint = typeof server.classes.endpoint; +export type Drive = typeof server.classes.drive; +export type Redirect = typeof server.classes.redirect; +export type File = typeof server.classes.file; +export type Invite = typeof server.classes.invite; + } + + +declare module '../index.js' { + interface Classes { + [server.classes.error]: { + requires: BaseProps | 'https://atomicdata.dev/properties/description'; + recommends: never; + }; +[server.classes.endpoint]: { + requires: BaseProps | 'https://atomicdata.dev/properties/description' | typeof server.properties.parameters; + recommends: never; + }; +[server.classes.drive]: { + requires: BaseProps; + recommends: 'https://atomicdata.dev/properties/read' | typeof server.properties.children | 'https://atomicdata.dev/properties/description' | 'https://atomicdata.dev/properties/subresources' | 'https://atomicdata.dev/properties/write'; + }; +[server.classes.redirect]: { + requires: BaseProps | typeof server.properties.destination; + recommends: typeof server.properties.redirectAgent; + }; +[server.classes.file]: { + requires: BaseProps | typeof server.properties.downloadUrl; + recommends: 'https://atomicdata.dev/properties/description' | typeof server.properties.filesize | typeof server.properties.filename | typeof server.properties.checksum | typeof server.properties.mimetype | typeof server.properties.internalId; + }; +[server.classes.invite]: { + requires: BaseProps | typeof server.properties.target; + recommends: typeof server.properties.write | typeof server.properties.createdBy | typeof server.properties.users | typeof server.properties.usagesLeft; + }; + } + + interface PropTypeMapping { + [server.properties.drives]: string[] +[server.properties.results]: string[] +[server.properties.property]: string +[server.properties.redirectAgent]: string +[server.properties.agent]: string +[server.properties.publicKey]: string +[server.properties.target]: string +[server.properties.usagesLeft]: number +[server.properties.users]: string[] +[server.properties.write]: boolean +[server.properties.filename]: string +[server.properties.filesize]: number +[server.properties.downloadUrl]: string +[server.properties.mimetype]: string +[server.properties.attachments]: string[] +[server.properties.createdBy]: string +[server.properties.checksum]: string +[server.properties.internalId]: string +[server.properties.children]: string[] +[server.properties.parameters]: string[] +[server.properties.destination]: string + } + + interface PropSubjectToNameMapping { + [server.properties.drives]: 'drives', +[server.properties.results]: 'results', +[server.properties.property]: 'property', +[server.properties.redirectAgent]: 'redirectAgent', +[server.properties.agent]: 'agent', +[server.properties.publicKey]: 'publicKey', +[server.properties.target]: 'target', +[server.properties.usagesLeft]: 'usagesLeft', +[server.properties.users]: 'users', +[server.properties.write]: 'write', +[server.properties.filename]: 'filename', +[server.properties.filesize]: 'filesize', +[server.properties.downloadUrl]: 'downloadUrl', +[server.properties.mimetype]: 'mimetype', +[server.properties.attachments]: 'attachments', +[server.properties.createdBy]: 'createdBy', +[server.properties.checksum]: 'checksum', +[server.properties.internalId]: 'internalId', +[server.properties.children]: 'children', +[server.properties.parameters]: 'parameters', +[server.properties.destination]: 'destination', + } +} diff --git a/browser/lib/src/ontology.ts b/browser/lib/src/ontology.ts index ae6fc3f9d..e40baa2e3 100644 --- a/browser/lib/src/ontology.ts +++ b/browser/lib/src/ontology.ts @@ -7,7 +7,14 @@ export type BaseObject = { // Extended via module augmentation // eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface Classes {} +export interface Classes { + 'unknown-subject': { + requires: BaseProps; + recommends: never; + }; +} + +export type UnknownClass = 'unknown-subject'; export type BaseProps = | 'https://atomicdata.dev/properties/isA' @@ -46,15 +53,19 @@ export type InferTypeOfValueInTriple< : JSONValue, > = Returns; -/** Type of the dynamically created resource.props field */ -export type QuickAccesPropType = { +type QuickAccesKnownPropType = { readonly [Prop in keyof PropsOfClass as PropSubjectToNameMapping[Prop]]: InferTypeOfValueInTriple< Class, Prop >; }; -export type OptionalClass = keyof Classes | never; +/** Type of the dynamically created resource.props field */ +export type QuickAccesPropType = + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Class extends UnknownClass ? any : QuickAccesKnownPropType; + +export type OptionalClass = keyof Classes | UnknownClass; // A map of all known classes and properties to their camelcased shortname. const globalReverseNameMapping = new Map(); diff --git a/browser/lib/src/resource.ts b/browser/lib/src/resource.ts index faf8b3fc8..8f32d4aa3 100644 --- a/browser/lib/src/resource.ts +++ b/browser/lib/src/resource.ts @@ -33,7 +33,8 @@ export const unknownSubject = 'unknown-subject'; * Describes an Atomic Resource, which has a Subject URL and a bunch of Property * / Value combinations. */ -export class Resource { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export class Resource { /** If the resource could not be fetched, we put that info here. */ public error?: Error; /** If the commit could not be saved, we put that info here. */ @@ -80,7 +81,7 @@ export class Resource { } public get props(): QuickAccesPropType { - const props: QuickAccesPropType = {}; + const props: QuickAccesPropType = {} as QuickAccesPropType; for (const prop of this.propvals.keys()) { const name = getKnownNameBySubject(prop); @@ -168,7 +169,7 @@ export class Resource { res.appliedCommitSignatures = this.appliedCommitSignatures; res.queuedFetch = this.queuedFetch; - return res; + return res as Resource; } /** Checks if the resource is both loaded and free from errors */ diff --git a/browser/lib/src/store.ts b/browser/lib/src/store.ts index 7ceb1354a..b5c186be2 100644 --- a/browser/lib/src/store.ts +++ b/browser/lib/src/store.ts @@ -16,11 +16,12 @@ import { JSONADParser, FileOrFileLike, OptionalClass, + UnknownClass, } from './index.js'; import { authenticate, fetchWebSocket, startWebsocket } from './websockets.js'; /** Function called when a resource is updated or removed */ -type ResourceCallback = ( +type ResourceCallback = ( resource: Resource, ) => void; /** Callback called when the stores agent changes */ @@ -120,6 +121,7 @@ export class Store { this.client.setFetch(fetchOverride); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any public addResources(...resources: Resource[]): void { for (const resource of resources) { this.addResource(resource); @@ -207,7 +209,7 @@ export class Store { /** * Always fetches resource from the server then adds it to the store. */ - public async fetchResourceFromServer( + public async fetchResourceFromServer( /** The resource URL to be fetched */ subject: string, opts: { @@ -309,7 +311,7 @@ export class Store { * done in the background . If the subject is undefined, an empty non-saved * resource will be returned. */ - public getResourceLoading( + public getResourceLoading( subject: string = unknownSubject, opts: FetchOpts = {}, ): Resource { @@ -350,7 +352,7 @@ export class Store { * store. Not recommended to use this for rendering, because it might cause * resources to be fetched multiple times. */ - public async getResourceAsync( + public async getResourceAsync( subject: string, ): Promise> { const found = this.resources.get(subject); diff --git a/browser/lib/src/urls.ts b/browser/lib/src/urls.ts index 98f25ac8d..b8bdd0f84 100644 --- a/browser/lib/src/urls.ts +++ b/browser/lib/src/urls.ts @@ -1,3 +1,6 @@ +/** + * @deprecated + */ export const classes = { agent: 'https://atomicdata.dev/classes/Agent', chatRoom: 'https://atomicdata.dev/classes/ChatRoom', @@ -40,7 +43,7 @@ export const classes = { ontology: 'https://atomicdata.dev/class/ontology', }; -/** List of commonly used Atomic Data Properties. */ +/** @deprecated List of commonly used Atomic Data Properties. */ export const properties = { /** Collection of all the AtomicData.dev properties */ allowsOnly: 'https://atomicdata.dev/properties/allowsOnly', @@ -184,6 +187,9 @@ export const endpoints = { import: '/import', }; +/** + * @deprecated + */ export const urls = { properties, endpoints, diff --git a/browser/pnpm-lock.yaml b/browser/pnpm-lock.yaml index cd41a1fac..6ecdc6017 100644 --- a/browser/pnpm-lock.yaml +++ b/browser/pnpm-lock.yaml @@ -279,6 +279,9 @@ importers: specifier: ^2.1.0 version: 2.1.0 devDependencies: + '@tomic/cli': + specifier: ^0.35.2 + version: link:../cli '@types/fast-json-stable-stringify': specifier: ^2.1.0 version: 2.1.0