diff --git a/.eslintrc.js b/.eslintrc.js index 7b88e098c51..94842dece0e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -215,7 +215,6 @@ module.exports = { 'ember-data-types/q/promise-proxies.ts', 'ember-data-types/q/minimum-serializer-interface.ts', 'ember-data-types/q/minimum-adapter-interface.ts', - 'ember-data-types/q/identifier.ts', 'ember-data-types/q/fetch-manager.ts', 'ember-data-types/q/ember-data-json-api.ts', '@types/@ember/polyfills/index.d.ts', diff --git a/packages/schema-record/src/index.ts b/packages/schema-record/src/index.ts index fc319b5baed..d007d5d1c56 100644 --- a/packages/schema-record/src/index.ts +++ b/packages/schema-record/src/index.ts @@ -1,6 +1,138 @@ -type Store = { peekRecord(identifier: StableRecordIdentifier): SchemaModel | unknown | null }; -type StableRecordIdentifier = { lid: string }; +// import type Store from '@ember-data/store'; +type Store = { schema: SchemaService, cache: Cache }; +import type { StableRecordIdentifier } from "@ember-data/types/q/identifier"; +import type { Cache } from "@ember-data/types/cache/cache"; -export default class SchemaModel { - constructor(store: Store, identifier: StableRecordIdentifier) {} +export const Destroy = Symbol('Destroy'); +export const RecordStore = Symbol('Store'); +export const Identifier = Symbol('Identifier'); + +export interface FieldSchema { + type: string; + name: string; + kind: 'attribute' | 'resource' | 'collection' | 'derived' | 'object' | 'array'; + options?: Record; +} + +type FieldSpec = { + // legacy support + attributes: Record; + relationships: Record; + // new support + fields: Map; +} + +export class SchemaService { + declare schemas: Map; + + constructor() { + this.schemas = new Map(); + } + + defineSchema(name: string, fields: FieldSchema[]): void { + const fieldSpec: FieldSpec = { + attributes: {}, + relationships: {}, + fields: new Map(), + }; + + fields.forEach((field) => { + fieldSpec.fields.set(field.name, field); + + if (field.kind === 'attribute') { + fieldSpec.attributes[field.name] = field; + } else if (field.kind === 'resource' || field.kind === 'collection') { + fieldSpec.relationships[field.name] = Object.assign({}, field, { + kind: field.kind === 'resource' ? 'belongsTo' : 'hasMany', + }); + } else { + throw new Error(`Unknown field kind ${field.kind}`); + } + }); + + this.schemas.set(name, fieldSpec); + } + + fields({ type }: { type: string }): FieldSpec['fields'] { + const schema = this.schemas.get(type); + + if (!schema) { + throw new Error(`No schema defined for ${type}`); + } + + return schema.fields; + } + + attributesDefinitionFor({ type }: { type: string }): FieldSpec['attributes'] { + const schema = this.schemas.get(type); + + if (!schema) { + throw new Error(`No schema defined for ${type}`); + } + + return schema.attributes; + } + + relationshipsDefinitionFor({ type }: { type: string }): FieldSpec['relationships'] { + const schema = this.schemas.get(type); + + if (!schema) { + throw new Error(`No schema defined for ${type}`); + } + + return schema.relationships; + } + + doesTypeExist(type: string): boolean { + return this.schemas.has(type); + } +} + +export default class SchemaRecord { + declare [RecordStore]: Store; + declare [Identifier]: StableRecordIdentifier; + + constructor(store: Store, identifier: StableRecordIdentifier) { + this[RecordStore] = store; + this[Identifier] = identifier; + + const schema = store.schema; + const cache = store.cache; + const fields = schema.fields(identifier); + + return new Proxy(this, { + get(target, prop) { + if (prop === Destroy) { + return target[Destroy]; + } + + if (prop === 'id') { + return identifier.id; + } + if (prop === '$type') { + return identifier.type; + } + const field = fields.get(prop as string); + if (!field) { + throw new Error(`No field named ${String(prop)} on ${identifier.type}`); + } + + if (field.kind === 'attribute') { + return cache.getAttr(identifier, prop as string); + } + + throw new Error(`Unknown field kind ${field.kind}`); + }, + }); + } + + [Destroy](): void {} +} + +export function instantiateRecord(store: Store, identifier: StableRecordIdentifier): SchemaRecord { + return new SchemaRecord(store, identifier); +} + +export function teardownRecord(record: SchemaRecord): void { + record[Destroy](); } diff --git a/packages/schema-record/tsconfig.json b/packages/schema-record/tsconfig.json index 2ae51769cd7..d20a894229a 100644 --- a/packages/schema-record/tsconfig.json +++ b/packages/schema-record/tsconfig.json @@ -45,6 +45,9 @@ "paths": { "@ember-data/env": ["../../private-build-infra/virtual-packages/env.d.ts"], + "@ember-data/store": ["../../store/src"], + "@ember-data/types": ["../../../ember-data-types"], + "@ember-data/types/*": ["../../../ember-data-types/*"], } } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc92fa05acd..b8c462b8f1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3424,9 +3424,24 @@ importers: '@babel/runtime': specifier: ^7.23.1 version: 7.23.1 + '@ember-data/graph': + specifier: workspace:5.5.0-alpha.9 + version: file:packages/graph(@babel/core@7.23.0)(@ember-data/store@5.5.0-alpha.9) + '@ember-data/json-api': + specifier: workspace:5.5.0-alpha.9 + version: file:packages/json-api(@babel/core@7.23.0)(@ember-data/graph@5.5.0-alpha.9)(@ember-data/request-utils@5.5.0-alpha.9)(@ember-data/store@5.5.0-alpha.9)(ember-inflector@4.0.2) '@ember-data/private-build-infra': specifier: workspace:5.5.0-alpha.9 version: link:../../packages/private-build-infra + '@ember-data/request': + specifier: workspace:5.5.0-alpha.9 + version: file:packages/request(@babel/core@7.23.0) + '@ember-data/store': + specifier: workspace:5.5.0-alpha.9 + version: file:packages/store(@babel/core@7.23.0)(@ember-data/tracking@5.5.0-alpha.9)(@ember/string@3.1.1)(@glimmer/tracking@1.1.2)(ember-source@5.3.0) + '@ember-data/tracking': + specifier: workspace:5.5.0-alpha.9 + version: file:packages/tracking(@babel/core@7.23.0) '@ember-data/unpublished-test-infra': specifier: workspace:5.5.0-alpha.9 version: link:../../packages/unpublished-test-infra @@ -3518,6 +3533,16 @@ importers: specifier: ^5.88.2 version: 5.88.2 dependenciesMeta: + '@ember-data/graph': + injected: true + '@ember-data/json-api': + injected: true + '@ember-data/request': + injected: true + '@ember-data/store': + injected: true + '@ember-data/tracking': + injected: true '@warp-drive/schema-record': injected: true @@ -3731,6 +3756,15 @@ packages: semver: 6.3.1 dev: true + /@babel/generator@7.22.15: + resolution: {integrity: sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.19 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.19 + jsesc: 2.5.2 + /@babel/generator@7.23.0: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} @@ -3744,13 +3778,13 @@ packages: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.17 /@babel/helper-builder-binary-assignment-operator-visitor@7.22.15: resolution: {integrity: sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} @@ -3770,11 +3804,11 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 '@babel/helper-member-expression-to-functions': 7.22.15 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.23.0) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 @@ -3808,6 +3842,17 @@ packages: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/types': 7.22.19 + /@babel/helper-function-name@7.23.0: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} @@ -3819,19 +3864,45 @@ packages: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-member-expression-to-functions@7.22.15: resolution: {integrity: sha512-qLNsZbgrNh0fDQBCPocSL8guki1hcPvltGDv/NxvUoABwFq7GkKSu1nRXeJkVZc+wJvne2E0RKQz+2SQrz6eAA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 + + /@babel/helper-module-transforms@7.22.17(@babel/core@7.23.0): + resolution: {integrity: sha512-XouDDhQESrLHTpnBtCKExJdyY4gJCdrvH2Pyv8r8kovX2U8G0dRUOT45T9XlbLtuu9CLXP15eusnkprhoPV5iQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0(supports-color@8.1.1) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.15 + + /@babel/helper-module-transforms@7.22.20(@babel/core@7.23.0): + resolution: {integrity: sha512-dLT7JVWIUUxKOs1UnJUBR3S70YK+pKX6AbJgB2vMIvEkZkrfJDbYDJesnPshtKV4LhDOR3Oc5YULeDizRek+5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0(supports-color@8.1.1) + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.0): resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==} @@ -3850,7 +3921,7 @@ packages: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} @@ -3878,23 +3949,34 @@ packages: '@babel/helper-member-expression-to-functions': 7.22.15 '@babel/helper-optimise-call-expression': 7.22.5 + /@babel/helper-replace-supers@7.22.9(@babel/core@7.23.0): + resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.0(supports-color@8.1.1) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.15 + '@babel/helper-optimise-call-expression': 7.22.5 + /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-skip-transparent-expression-wrappers@7.22.5: resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.17 /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} @@ -3916,9 +3998,9 @@ packages: resolution: {integrity: sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.23.0 + '@babel/helper-function-name': 7.22.5 '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 /@babel/helpers@7.23.1(supports-color@8.1.1): resolution: {integrity: sha512-chNpneuK18yW5Oxsr+t553UZzzAs3aZnFm4bxhebsNTeshrC95yA7l5yl7GBAG+JG1rF0F7zzD2EixK9mWSDoA==} @@ -3943,9 +4025,16 @@ packages: engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 dev: true + /@babel/parser@7.22.16: + resolution: {integrity: sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.19 + /@babel/parser@7.23.0: resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} @@ -3984,19 +4073,6 @@ packages: '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-proposal-decorators@7.22.15(@babel/core@7.23.0): - resolution: {integrity: sha512-kc0VvbbUyKelvzcKOSyQUSVVXS5pT3UhRB0e3c9An86MvLqs+gx0dN4asllrDluqSa3m9YyooXKGOFVomnyFkg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.23.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.22.15(@babel/core@7.23.0) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/plugin-syntax-decorators': 7.22.10(@babel/core@7.23.0) - /@babel/plugin-proposal-decorators@7.23.0(@babel/core@7.23.0): resolution: {integrity: sha512-kYsT+f5ARWF6AdFmqoEEp+hpqxEB8vGmRWfw2aj78M2vTwS2uHW91EF58iFm1Z9U8Y/RrLu2XKJn46P9ca1b0w==} engines: {node: '>=6.9.0'} @@ -4009,7 +4085,6 @@ packages: '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) '@babel/helper-split-export-declaration': 7.22.6 '@babel/plugin-syntax-decorators': 7.22.10(@babel/core@7.23.0) - dev: true /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.23.0): resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} @@ -4312,10 +4387,10 @@ packages: '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-compilation-targets': 7.22.15 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 + '@babel/helper-function-name': 7.22.5 '@babel/helper-optimise-call-expression': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.23.0) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 @@ -4404,7 +4479,7 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-compilation-targets': 7.22.15 - '@babel/helper-function-name': 7.23.0 + '@babel/helper-function-name': 7.22.5 '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-transform-json-strings@7.22.11(@babel/core@7.23.0): @@ -4452,7 +4527,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-module-transforms': 7.22.20(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-transform-modules-commonjs@7.22.15(@babel/core@7.23.0): @@ -4462,7 +4537,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-module-transforms': 7.22.17(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.22.5 @@ -4476,6 +4551,7 @@ packages: '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-simple-access': 7.22.5 + dev: true /@babel/plugin-transform-modules-systemjs@7.22.11(@babel/core@7.23.0): resolution: {integrity: sha512-rIqHmHoMEOhI3VkVf5jQ15l539KrwhzqcBO6wdCNWPWc/JWt9ILNYNUssbRpeq0qWns8svuw8LnMNCvWBIJ8wA==} @@ -4485,7 +4561,7 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-module-transforms': 7.22.20(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 @@ -4496,7 +4572,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) - '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.0) + '@babel/helper-module-transforms': 7.22.20(@babel/core@7.23.0) '@babel/helper-plugin-utils': 7.22.5 /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.23.0): @@ -4559,7 +4635,7 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.20(@babel/core@7.23.0) + '@babel/helper-replace-supers': 7.22.9(@babel/core@7.23.0) /@babel/plugin-transform-optional-catch-binding@7.22.11(@babel/core@7.23.0): resolution: {integrity: sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ==} @@ -4808,7 +4884,7 @@ packages: '@babel/plugin-transform-logical-assignment-operators': 7.22.11(@babel/core@7.23.0) '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.23.0) '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.23.0) - '@babel/plugin-transform-modules-commonjs': 7.23.0(@babel/core@7.23.0) + '@babel/plugin-transform-modules-commonjs': 7.22.15(@babel/core@7.23.0) '@babel/plugin-transform-modules-systemjs': 7.22.11(@babel/core@7.23.0) '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.23.0) '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.23.0) @@ -4835,7 +4911,7 @@ packages: '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.23.0) '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.23.0) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.23.0) - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.23.0) babel-plugin-polyfill-corejs3: 0.8.3(@babel/core@7.23.0) babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.23.0) @@ -4941,7 +5017,7 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.23.0 + '@babel/types': 7.22.19 esutils: 2.0.3 /@babel/preset-typescript@7.23.0(@babel/core@7.23.0): @@ -4977,27 +5053,44 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.22.16 + '@babel/types': 7.22.19 /@babel/traverse@7.22.15: resolution: {integrity: sha512-DdHPwvJY0sEeN4xJU5uRLmZjgMMDIvMPniLuYzUVXj/GGzysPl0/fwt44JBkyUIzGJPV8QgHMcQdQ34XFuKTYQ==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.0 + '@babel/generator': 7.22.15 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-function-name': 7.23.0 + '@babel/helper-function-name': 7.22.5 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.22.16 + '@babel/types': 7.22.19 debug: 4.3.4(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true + /@babel/traverse@7.22.20: + resolution: {integrity: sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.13 + '@babel/generator': 7.22.15 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.22.16 + '@babel/types': 7.22.19 + debug: 4.3.4(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + /@babel/traverse@7.23.0(supports-color@8.1.1): resolution: {integrity: sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==} engines: {node: '>=6.9.0'} @@ -5023,6 +5116,14 @@ packages: '@babel/helper-validator-identifier': 7.22.15 to-fast-properties: 2.0.0 + /@babel/types@7.22.17: + resolution: {integrity: sha512-YSQPHLFtQNE5xN9tHuZnzu8vPr61wVTBZdfv1meex1NBosa4iT05k/Jw06ddJugi4bk7The/oSwQGFcksmEJQg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.15 + to-fast-properties: 2.0.0 + /@babel/types@7.22.19: resolution: {integrity: sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==} engines: {node: '>=6.9.0'} @@ -9671,7 +9772,7 @@ packages: dependencies: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.0) - '@babel/plugin-proposal-decorators': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-proposal-decorators': 7.23.0(@babel/core@7.23.0) '@babel/preset-env': 7.22.15(@babel/core@7.23.0) '@embroider/macros': 1.13.1(@babel/core@7.23.0) '@embroider/shared-internals': 2.4.0(supports-color@8.1.1) @@ -9748,7 +9849,7 @@ packages: '@babel/core': 7.23.0(supports-color@8.1.1) '@babel/helper-compilation-targets': 7.22.15 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.23.0) - '@babel/plugin-proposal-decorators': 7.22.15(@babel/core@7.23.0) + '@babel/plugin-proposal-decorators': 7.23.0(@babel/core@7.23.0) '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.23.0) '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.23.0) '@babel/plugin-transform-class-static-block': 7.22.11(@babel/core@7.23.0) @@ -10306,8 +10407,8 @@ packages: resolution: {integrity: sha512-89oVHVJwmLDvGvAUWgS87KpBoRhy3aZ6U0Ql6HOmU4TrPkyaa8pM0W81wj9cIwjYprcQtN9EwzZMHnq46+oUyw==} engines: {node: 8.* || 10.* || >= 12} dependencies: - '@babel/parser': 7.23.0 - '@babel/traverse': 7.23.0(supports-color@8.1.1) + '@babel/parser': 7.22.16 + '@babel/traverse': 7.22.20 recast: 0.18.10 transitivePeerDependencies: - supports-color diff --git a/tests/schema-record/app/models/user-setting.ts b/tests/schema-record/app/models/user-setting.ts deleted file mode 100644 index e8f3511d0a0..00000000000 --- a/tests/schema-record/app/models/user-setting.ts +++ /dev/null @@ -1,5 +0,0 @@ -import Model, { attr } from '@ember-data/model'; - -export default class UserSetting extends Model { - @attr declare name: string; -} diff --git a/tests/schema-record/app/services/store.ts b/tests/schema-record/app/services/store.ts index 41ac00034c8..58814e46572 100644 --- a/tests/schema-record/app/services/store.ts +++ b/tests/schema-record/app/services/store.ts @@ -1,7 +1,7 @@ +import type SchemaRecord from '@warp-drive/schema-record'; +import { instantiateRecord, teardownRecord } from '@warp-drive/schema-record'; + import JSONAPICache from '@ember-data/json-api'; -import type Model from '@ember-data/model'; -import { instantiateRecord, teardownRecord } from '@ember-data/model'; -import { buildSchema, modelFor } from '@ember-data/model/hooks'; import RequestManager from '@ember-data/request'; import Fetch from '@ember-data/request/fetch'; import DataStore, { CacheHandler } from '@ember-data/store'; @@ -16,23 +16,17 @@ export default class Store extends DataStore { const manager = (this.requestManager = new RequestManager()); manager.use([Fetch]); manager.useCache(CacheHandler); - - this.registerSchema(buildSchema(this)); } createCache(capabilities: CacheCapabilitiesManager): Cache { return new JSONAPICache(capabilities); } - instantiateRecord(identifier: StableRecordIdentifier, createRecordArgs: { [key: string]: unknown }): unknown { - return instantiateRecord.call(this, identifier, createRecordArgs); - } - - teardownRecord(record: Model): void { - return teardownRecord.call(this, record); + instantiateRecord(identifier: StableRecordIdentifier): SchemaRecord { + return instantiateRecord(this, identifier); } - modelFor(type: string) { - return modelFor.call(this, type); + teardownRecord(record: SchemaRecord): void { + return teardownRecord(record); } } diff --git a/tests/schema-record/config/environment.js b/tests/schema-record/config/environment.js index 265be9f8b5e..7e28113b93b 100644 --- a/tests/schema-record/config/environment.js +++ b/tests/schema-record/config/environment.js @@ -2,7 +2,7 @@ module.exports = function (environment) { let ENV = { - modulePrefix: 'builders-test-app', + modulePrefix: 'schema-record-test-app', environment, rootURL: '/', locationType: 'history', diff --git a/tests/schema-record/package.json b/tests/schema-record/package.json index ff919195465..a5639ab64df 100644 --- a/tests/schema-record/package.json +++ b/tests/schema-record/package.json @@ -22,11 +22,31 @@ "dependenciesMeta": { "@warp-drive/schema-record": { "injected": true + }, + "@ember-data/store": { + "injected": true + }, + "@ember-data/request": { + "injected": true + }, + "@ember-data/tracking": { + "injected": true + }, + "@ember-data/json-api": { + "injected": true + }, + "@ember-data/graph": { + "injected": true } }, "devDependencies": { "@babel/core": "^7.23.0", "@babel/runtime": "^7.23.1", + "@ember-data/store": "workspace:5.5.0-alpha.9", + "@ember-data/request": "workspace:5.5.0-alpha.9", + "@ember-data/tracking": "workspace:5.5.0-alpha.9", + "@ember-data/json-api": "workspace:5.5.0-alpha.9", + "@ember-data/graph": "workspace:5.5.0-alpha.9", "@warp-drive/schema-record": "workspace:5.5.0-alpha.9", "@ember-data/private-build-infra": "workspace:5.5.0-alpha.9", "@ember-data/unpublished-test-infra": "workspace:5.5.0-alpha.9", diff --git a/tests/schema-record/tests/integration/basic-fields-test.ts b/tests/schema-record/tests/integration/basic-fields-test.ts new file mode 100644 index 00000000000..67b4e300683 --- /dev/null +++ b/tests/schema-record/tests/integration/basic-fields-test.ts @@ -0,0 +1,49 @@ +import { SchemaService } from '@warp-drive/schema-record'; +import { module, test } from 'qunit'; + +import { setupTest } from 'ember-qunit'; + +import type Store from '@ember-data/store'; + +interface User { + id: string | null; + $type: 'user'; + name: string; +} + +module('Integration | basic fields', function (hooks) { + setupTest(hooks); + + test('Simple Fields Work As Expected', function (assert) { + const store = this.owner.lookup('service:store') as Store; + const schema = new SchemaService(); + store.registerSchema(schema); + + schema.defineSchema('user', [ + { + name: 'name', + type: 'string', + kind: 'attribute', + }, + ]); + + const record = store.createRecord('user', { name: 'Rey Skybarker' }) as User; + + assert.strictEqual(record.id, null, 'id is accessible'); + assert.strictEqual(record.$type, 'user', '$type is accessible'); + + assert.strictEqual(record.name, 'Rey Skybarker', 'name is accessible'); + + try { + // @ts-expect-error intentionally accessing unknown field + record.lastName; + assert.ok(false, 'should error when accessing unknown field'); + } catch (e) { + assert.strictEqual( + (e as Error).message, + 'No field named lastName on user', + 'should error when accessing unknown field' + ); + } + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 5e5b6a2324d..60895b4e6cd 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,6 @@ "ember-data-types/q/promise-proxies.ts", "ember-data-types/q/minimum-serializer-interface.ts", "ember-data-types/q/minimum-adapter-interface.ts", - "ember-data-types/q/identifier.ts", "ember-data-types/q/fetch-manager.ts", "ember-data-types/q/ember-data-json-api.ts", "tests/graph/tests/integration/graph/polymorphism/implicit-keys-test.ts", diff --git a/tsconfig.root.json b/tsconfig.root.json index bf047b8f783..aa5fecd6292 100644 --- a/tsconfig.root.json +++ b/tsconfig.root.json @@ -53,6 +53,8 @@ "@warp-drive/holodeck/*": ["packages/holodeck/dist/*"], "@ember-data/request": ["packages/request/addon"], "@ember-data/request/*": ["packages/request/addon/*"], + "@warp-drive/schema-record": ["packages/schema-record/addon"], + "@warp-drive/schema-record/*": ["packages/schema-record/addon/*"], "@ember-data/request-utils": ["packages/request-utils/src"], "@ember-data/request-utils/*": ["packages/request-utils/src/*"], "@ember-data/rest": ["packages/rest/src"],